XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Конструкция for in может быть использована для итерации по итераторам (Iterator). Один из самых простых способов создать итератор это использовать диапазон значений a..b. Это вернёт нам значения от a (включительно) до b (исключительно) за один шаг.
Давайте напишем FizzBuzz, используя for вместо while.
fn main() {
// `n` будет принимать значения: 1, 2, ..., 100 с каждой итерации
for n in 1..101 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Также, может быть использован диапазон a..=b, включающий оба конца. Код выше может быть записан следующим образом:
fn main() {
// `n` будет принимать значения: 1, 2, ..., 100 с каждой итерации
for n in 1..=100 {
if n % 15 == 0 {
println!("fizzbuzz");
} else if n % 3 == 0 {
println!("fizz");
} else if n % 5 == 0 {
println!("buzz");
} else {
println!("{}", n);
}
}
}
הההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההההה
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Конструкция for in может взаимодействовать с итератором разными способами. Как обсуждается далее про типаж Iterator, цикл for применяет к предоставленной коллекции метод into_iter, чтобы преобразовать её в итератор. Однако, это не единственный способ преобразования коллекции в итератор.
Каждый из методов into_iter, iter и iter_mut преобразует коллекцию в итератор по своему, предоставляя разные отображения содержащихся данных.
• iter - эта функция заимствует каждый элемент коллекции на каждой итерации. Благодаря этому, он оставляет коллекцию нетронутой и доступной для использования после цикла.
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter() {
match name {
&"Ferris" => println!("Программисты Rust вокруг нас!"),
_ => println!("Привет {}", name),
}
}
}
• into_iter - эта функция потребляет коллекцию так что на каждой итерации предоставляются данные. Коллекция больше не доступна для использования так как владение ею перешло в эту функцию.
fn main() {
let names = vec!["Bob", "Frank", "Ferris"];
for name in names.into_iter() {
match name {
"Ferris" => println!("Программисты Rust вокруг нас!"),
_ => println!("Привет {}", name),
}
}
}
• iter_mut - эта функция делает изменяемое заимствование каждого элемента коллекции, позволяя изменять коллекцию на месте.
fn main() {
let mut names = vec!["Bob", "Frank", "Ferris"];
for name in names.iter_mut() {
*name = match name {
&mut "Ferris" => "Программисты Rust вокруг нас!",
_ => "Привет",
}
}
println!("имена: {:?}", names);
}
В вышеуказанных кусках кода, обратите на ветку match, которая имеет ключевое отличие в зависимости от типа выполнения итераций. Разница в типе, конечно, подразумевает различные действия, которые могут быть выполнены.