このコードは機能し、「b」を出力します。
_fn main() {
let s = "abc";
let ch = s.chars().nth(1).unwrap();
println!("{}", ch);
}
_
一方、このコードは不一致タイプのエラーになります。
_fn main() {
let s = "abc";
let n: u32 = 1;
let ch = s.chars().nth(n).unwrap();
println!("{}", ch);
}
_
_error[E0308]: mismatched types
--> src/main.rs:5:28
|
5 | let ch = s.chars().nth(n).unwrap();
| ^ expected usize, found u32
_
何らかの外部的な理由により、変数n
に_u32
_タイプを使用する必要があります。 _u32
_をusize
に変換してnth()
で使用するにはどうすればよいですか?
as
演算子は、すべての数値タイプで機能します。
let ch = s.chars().nth(n as usize).unwrap();
Rustは整数をキャストするように強制し、符号またはオーバーフローを確実に認識します。
整数定数には、型の接尾辞を付けることができます。
let n = 1u32;
ただし、-1i32
などの負の定数は内部では-
1i32
であることに注意してください。
明示的な型指定なしで宣言された整数変数は{integer}
として示され、メソッド呼び出しの1つから適切に推測されます。
あなたができる最も慎重なことは TryFrom
を使用し、値がusize
に収まらない場合にパニックすることです:
use std::convert::TryFrom;
fn main() {
let s = "abc";
let n: u32 = 1;
let n_us = usize::try_from(n).unwrap();
let ch = s.chars().nth(n_us).unwrap();
println!("{}", ch);
}
盲目的にas
を使用すると、usize
が32ビットより小さいプラットフォームで実行すると、コードが不可解な方法で失敗します。たとえば、一部のマイクロコントローラーは、ネイティブサイズとして16ビット整数を使用します。
fn main() {
let n: u32 = 0x1_FF_FF;
// Pretend that `usize` is 16-bit
let n_us: u16 = n as u16;
println!("{}, {}", n, n_us); // 131071, 65535
}
コードをコンパイルしようとすると、かなり異なる答えが得られます。数値_1
_を型_i32
_の変数に置き換えます。
_error[E0308]: mismatched types
--> src/main.rs:5:28
|
5 | let ch = s.chars().nth(n).unwrap();
| ^ expected usize, found i32
help: you can convert an `i32` to `usize` and panic if the converted value wouldn't fit
|
5 | let ch = s.chars().nth(n.try_into().unwrap()).unwrap();
|
_
つまり、コンパイラーは、TryInto
に依存して返される特性 TryFrom
を利用するn.try_into().unwrap()
を使用することをお勧めします_Result<T, T::Error>
_。そのため、.unwrap()
を使用して結果を抽出する必要があります