Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

цикли for

for і range

Конструкцію for in можна використовувати для ітерації через Iterator. Один із найпростіших способів створити ітератор — використати нотацію діапазону a..b. Це дає значення від a (включно) до b (виключно) з кроком один.

Давайте напишемо FizzBuzz, використовуючи for замість while.

fn main() {
    // `n` will take the values: 1, 2, ..., 100 in each iteration
    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);
        }
    }
}

Альтернативно, a..=b можна використати для діапазону, який є включним з обох кінців. Вище можна записати так:

fn main() {
    // `n` will take the values: 1, 2, ..., 100 in each iteration
    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);
        }
    }
}

Просто пам’ятайте, що хоча ви можете скомпілювати код, коли a>b, цикл ніколи не виконується.

for i in 10..1{
println!("fizzbuzz");
}

Якщо ви хочете рахувати у зворотному напрямку, вам потрібно використати .rev() замість цього

for i in (1..10).rev(){
println!("fizzbuzz");
}

for і ітератори

Конструкція for in може взаємодіяти з Iterator кількома способами. Як обговорювалося в розділі про трейт 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!("There is a rustacean among us!"),
            // TODO ^ Try deleting the & and matching just "Ferris"
            _ => println!("Hello {}", name),
        }
    }

    println!("names: {:?}", names);
}
  • into_iter - Це споживає колекцію, так що на кожній ітерації надаються точні дані. Щойно колекцію було спожито, вона більше не доступна для повторного використання, оскільки її було ‘переміщено’ всередині циклу.
fn main() {
    let names = vec!["Bob", "Frank", "Ferris"];

    for name in names.into_iter() {
        match name {
            "Ferris" => println!("There is a rustacean among us!"),
            _ => println!("Hello {}", name),
        }
    }

    // `names` has been 'moved' and can no longer be used.
    // Try uncommenting the line below to see the compiler error:
    // println!("names: {:?}", names);
}
  • iter_mut - Це змінно запозичує кожен елемент колекції, дозволяючи змінювати колекцію на місці.
fn main() {
    let mut names = vec!["Bob", "Frank", "Ferris"];

    for name in names.iter_mut() {
        *name = match name {
            &mut "Ferris" => "There is a rustacean among us!",
            _ => "Hello",
        }
    }

    println!("names: {:?}", names);
}

У наведених вище фрагментах зверніть увагу на тип гілки match, це ключова різниця в типах ітерації. Різниця в типі, звісно, передбачає різні дії, які можна виконати.

Дивіться також:

Iterator