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(미포함)까지의 값을 1씩 증가시키며 생성합니다.

while 대신 for를 사용하여 FizzBuzz를 작성해 봅시다.

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);
        }
    }
}

또는 양쪽 끝을 모두 포함하는 범위에는 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);
        }
    }
}

for와 이터레이터

for in 구문은 여러 방식으로 Iterator와 상호작용할 수 있습니다. Iterator 트레이트 섹션에서 다룬 것처럼, 기본적으로 for 루프는 컬렉션에 into_iter 함수를 적용합니다. 하지만 이것이 컬렉션을 이터레이터로 변환하는 유일한 방법은 아닙니다.

into_iter, iter, iter_mut은 모두 내부 데이터에 대해 서로 다른 뷰를 제공함으로써 컬렉션을 이터레이터로 변환하는 작업을 서로 다른 방식으로 처리합니다.

  • iter - 매 반복마다 컬렉션의 각 요소를 빌려옵니다. 따라서 컬렉션은 수정되지 않은 상태로 유지되며 루프 이후에도 재사용할 수 있습니다.
fn main() {
    let names = vec!["밥", "프랭크", "페리스"];

    for name in names.iter() {
        match name {
            &"페리스" => println!("우리 중에 러스타시안(rustacean)이 있습니다!"),
            // TODO ^ &를 삭제하고 그냥 "Ferris"와 매칭해 보세요
            _ => println!("안녕 {}", name),
        }
    }

    println!("이름들: {:?}", names);
}
  • into_iter - 컬렉션을 소비(consume)하여 각 반복마다 실제 데이터를 제공합니다. 컬렉션이 소비되면 루프 내에서 ’이동(moved)’된 것이므로 더 이상 재사용할 수 없습니다.
fn main() {
    let names = vec!["밥", "프랭크", "페리스"];

    for name in names.into_iter() {
        match name {
            "페리스" => println!("우리 중에 러스타시안(rustacean)이 있습니다!"),
            _ => println!("안녕 {}", name),
        }
    }

    println!("이름들: {:?}", names);
    // FIXME ^ 이 줄을 주석 처리하세요
}
  • iter_mut - 컬렉션의 각 요소를 가변적으로 빌려와서, 컬렉션을 제자리에서 수정할 수 있게 합니다.
fn main() {
    let mut names = vec!["밥", "프랭크", "페리스"];

    for name in names.iter_mut() {
        *name = match name {
            &mut "페리스" => "우리 중에 러스타시안(rustacean)이 있습니다!",
            _ => "안녕",
        }
    }

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

위의 스니펫에서 match 분기의 타입에 주목하세요. 이것이 반복 방식의 핵심적인 차이점입니다. 타입의 차이는 물론 수행할 수 있는 작업의 차이를 의미합니다.

참고:

Iterator