Можно ли объявить тип переменной в Rust для циклов?
C++ пример:
for (long i = 0; i < 101; i++) {
//...
}
В Rust я попробовал:
for i: i64 in 1..100 {
// ...
}
Я мог бы просто объявить let i: i64 =
var перед циклом for, но я бы лучше изучил правильный способ сделать это, но это привело к
error: expected one of `@` or `in`, found `:`
--> src/main.rs:2:10
|
2 | for i: i64 in 1..100 {
| ^ expected one of `@` or `in` here
5 ответов
Вы можете использовать целочисленный суффикс для одного из литералов, которые вы использовали в диапазоне. Вывод типа сделает все остальное:
for i in 1i64..101 {
println!("{}", i);
}
Нет, невозможно объявить тип переменной в for
петля.
Вместо этого, более общий подход (например, применим также к enumerate()
) представляет let
связывание путем разрушения элемента внутри тела цикла.
Пример:
for e in bytes.iter().enumerate() {
let (i, &item): (usize, &u8) = e; // here
if item == b' ' {
return i;
}
}
Если ваша переменная цикла является результатом вызова функции, которая возвращает универсальный тип:
let input = ["1", "two", "3"];
for v in input.iter().map(|x| x.parse()) {
println!("{:?}", v);
}
error[E0284]: type annotations required: cannot resolve `<_ as std::str::FromStr>::Err == _`
--> src/main.rs:3:37
|
3 | for v in input.iter().map(|x| x.parse()) {
| ^^^^^
Вы можете использовать турбовину, чтобы указать типы:
for v in input.iter().map(|x| x.parse::<i32>()) {
// ^^^^^^^
println!("{:?}", v);
}
Или вы можете использовать полный синтаксис:
for v in input.iter().map(|x| <i32 as std::str::FromStr>::from_str(x)) {
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
println!("{:?}", v);
}
Смотрите также:
Попробуйте использовать as:
for i in 1..100 as i64 {
// ...
}
Раньше было обсуждение , где это требовалось, за которым последовал фактический RFC.
Однако похоже, что дискуссия была отложена, потому что мало кто действительно интересовался этой темой.
В настоящее время, если вы абсолютно хотите аннотировать, кажется, что лучший вариант, который у вас есть, это:
fn main() {
let my_vec: Vec<i32> = vec![-1, 22, -333];
for i in my_vec.iter() {
let _: &i32 = i;
println!("{}", i);
}
}
Как видите, это не работает, если тип не совпадает:
fn main() {
let my_vec: Vec<i32> = vec![-1, 22, -333];
for i in my_vec.iter() {
let _: &i16 = i;
println!("{}", i);
}
}
--> src/main.rs:4:23
|
4 | let _: &i16 = i;
| ---- ^ expected `i16`, found `i32`
| |
| expected due to this
|
= note: expected reference `&i16`
found reference `&i32`
Конечно, из-за автоматического разыменования этот метод не может различать&i32
и&&i32
, что может быть проблемой в некоторых случаях:
fn main() {
let my_vec: Vec<i32> = vec![-1, 22, -333];
for i in my_vec.iter() {
let _: &i32 = &i; // Compiles, but the right side is &&i32
println!("{}", i);
}
}
Но в целом, на мой взгляд, это должно внушать доверие потенциальным рецензентам.