数値型を安全かつ慣用的に変換するにはどうすればよいでしょうか? 質問する

数値型を安全かつ慣用的に変換するにはどうすればよいでしょうか? 質問する

編集者注: この質問は Rust 1.0 より前のバージョンからのものであり、Rust 1.0 には存在しないいくつかの項目を参照しています。回答には依然として貴重な情報が含まれています。

usize(例えば)を に変換する慣用的な方法は何ですかu32

例えば、4294967295us as u32作品を使った鋳造やRust 0.12 の型キャストに関するリファレンスドキュメント言う

数値は任意の数値型にキャストできます。生のポインタ値は、任意の整数型または生のポインタ型にキャストできます。その他のキャストはサポートされていないため、コンパイルに失敗します。

しかし、4294967296us as u32何も言わずにオーバーフローし、結果 0 を返します。

私は見つけたToPrimitiveそしてFromPrimitiveのような優れた機能を提供しますto_u32() -> Option<u32>が、不安定であるとマークされています。

#[unstable(feature = "core", reason = "trait is likely to be removed")]

数値型 (およびポインタ型) を変換する慣用的な (そして安全な) 方法は何ですか?

isize/のプラットフォーム依存のサイズは、usize私がこの質問をしている理由の 1 つです。元々のシナリオでは、 から に変換して、 でツリーを表現できるようにしたいと考えていましたu32(usizeたとえばVec<u32>、 のlet t = Vec![0u32, 0u32, 1u32]場合、ノード 2 の祖父母を取得するには になります)。そして、が 32 ビット未満のt[t[2us] as usize]場合、どのように失敗するのか疑問に思いました。usize

ベストアンサー1

値の変換

他のタイプに完全に適合するタイプから

問題ありません。From損失が発生していないことを明示的に示す特性:

fn example(v: i8) -> i32 {
    i32::from(v) // or v.into()
}

を使用することもできますasが、必要がない場合は使用しないことをお勧めします (以下を参照)。

fn example(v: i8) -> i32 {
    v as i32
}

他のタイプに完全には当てはまらないタイプから

一般的に意味を成す単一の方法はありません。1 つのスペースに 2 つのものを収める方法を尋ねているのです。最初の試みとして良いのは、値が収まる場合はOption— を使用し、そうでない場合は — を使用することです。その後、必要に応じてプログラムを失敗させたり、デフォルト値を代入したりできます。SomeNone

Rust 1.34以降では、TryFrom:

use std::convert::TryFrom;

fn example(v: i32) -> Option<i8> {
    i8::try_from(v).ok()
}

その前に、同様のコードを自分で書く必要があります:

fn example(v: i32) -> Option<i8> {
    if v > std::i8::MAX as i32 {
        None
    } else {
        Some(v as i8)
    }
}

他のタイプに完全に適合するかどうかはわからない

表現できるisize数字の範囲usizeプラットフォームに応じて変更コンパイルする対象TryFromに応じて、現在プラットホーム。

参照:

as

しかし、4294967296us as u32何も言わずにオーバーフローし、結果は0になります。

When converting to a smaller type, as just takes the lower bits of the number, disregarding the upper bits, including the sign:

fn main() {
    let a: u16 = 0x1234;
    let b: u8 = a as u8;
    println!("0x{:04x}, 0x{:02x}", a, b); // 0x1234, 0x34

    let a: i16 = -257;
    let b: u8 = a as u8;
    println!("0x{:02x}, 0x{:02x}", a, b); // 0xfeff, 0xff
}

See also:

About ToPrimitive / FromPrimitive

RFC 369, Num Reform, states:

Ideally [...] ToPrimitive [...] would all be removed in favor of a more principled way of working with C-like enums

In the meantime, these traits live on in the num crate:

おすすめ記事