콘텐츠로 이동
Xen / docs

문서 검색

한국어 · v0.1.0-demo.2

검색어를 입력하세요.

    EN
    Xen / learn v0.1.0-demo.2

    슬라이스와 이터레이터

    컬렉션을 함수에 전달하기 전에 원소의 독립 사본이 필요한지, 원본을 잠깐 읽을지, 소유권을 넘길지 정해야 합니다. 이 장은 컬렉션과 소유권을 연결합니다.

    방법원본과의 관계원소 제약
    Vec<T>를 값으로 전달복제 가능한 원소라면 독립 사본, 이동 전용 원소라면 벡터 전체 이동원소 타입에 따라 다름
    as_slice(), slice(start, end)원소를 복사하지 않는 읽기 전용 뷰뷰의 마지막 사용까지 원본 변경·이동 제한
    .iter()원본을 빌려 순회하며 복사·복제한 원소 제공복사·복제 가능한 원소 필요
    .into_iter()벡터 소유권을 가져와 원소를 순서대로 제공Box, File 같은 이동 전용 원소도 가능

    for value in values가 자동으로 벡터 이터레이터를 만들지는 않습니다. 이터레이터 메서드에는 use std.iter;가 필요합니다.

    뷰의 마지막 사용과 변환 파이프라인

    섹션 제목: “뷰의 마지막 사용과 변환 파이프라인”

    다음을 views_and_iterators.xen으로 저장하세요.

    views_and_iterators.xen
    use std.iter;
    fn doubled(value: Int) -> Int {
    return value * 2;
    }
    #![explc]
    fn over_two(value: &Int) -> Bool {
    return *value > 2;
    }
    fn main() {
    let mut values = [1, 2, 3];
    let view = values.slice(0, 2);
    println(view.get(1));
    values.push(4);
    for value in values.iter().map(doubled).filter(over_two) {
    println(value);
    }
    let owned = [box(10), box(20)];
    for item in owned.into_iter() {
    println(item.into_inner());
    }
    }
    터미널 창
    xen check views_and_iterators.xen
    xen run views_and_iterators.xen
    views_and_iterators.stdout
    2
    4
    6
    8
    10
    20

    slice(0, 2)는 0번과 1번 원소를 보는 뷰입니다. 끝 인덱스 2는 포함하지 않습니다. println(view.get(1))이 뷰의 마지막 사용이므로 다음 줄에서 values.push(4)를 할 수 있습니다.

    map(doubled)가 각 값을 두 배로 만든 뒤 filter(over_two)가 변환된 값 중 2보다 큰 값을 남깁니다. 콜백은 체인을 만드는 순간이 아니라 순회할 때 실행됩니다. filter의 콜백은 원소의 공유 참조를 받으므로 over_two에 #![explc]가 있습니다. main에서는 &value 같은 명시적 참조를 만들지 않습니다.

    마지막 벡터는 Box<Int>를 담습니다. .into_iter()로 상자 소유권을 하나씩 받은 뒤 into_inner()로 정수를 꺼냅니다. 순회 뒤에는 owned를 다시 사용할 수 없습니다.

    뷰를 사용하는 동안 변경하면 생기는 오류

    섹션 제목: “뷰를 사용하는 동안 변경하면 생기는 오류”

    다음은 의도적인 오류입니다. xen check borrow_error.xen으로 확인하세요.

    borrow_error.xen
    fn main() {
    let mut values = [1, 2];
    let view = values.as_slice();
    values.push(3);
    println(view.get(0));
    }
    borrow_error.stderr
    cannot mutate 'values' while it is borrowed

    push 뒤에도 view를 사용하므로 원본 변경이 거부됩니다. println(view.get(0));을 push보다 앞에 옮기면 뷰의 사용을 끝낸 뒤 변경할 수 있습니다. 새 벡터에 값을 복사하는 방법도 있지만, Slice를 만드는 것 자체는 복사가 아닙니다.

    Box나 File은 values[0]이나 get(0)으로 복사해 꺼낼 수 없습니다. 원본에서 제거하려면 pop(), replace() 또는 .into_iter()를 사용하세요. 읽기만 필요하다면 explc 범위에서 &values[index]를 만들 수 있습니다. 가변 원소 참조는 지원하지 않습니다.

    pop()은 빈 벡터에서, get()은 잘못된 인덱스에서 런타임 오류가 됩니다. get()이 Option을 반환한다고 가정하지 말고 길이를 먼저 확인하세요.

    읽기 전용 뷰는 함수에서 반환하거나 벡터 원소로 저장할 수 없고, 가변 뷰도 지원하지 않습니다. String.as_bytes()는 Slice<U8>을 만듭니다. 바이트 뷰 역시 글자 단위 인덱스를 제공하는 것은 아닙니다.

    메서드는 컬렉션 학습 문서와 이터레이터 레퍼런스에서 조회하세요.

    성공 예제의 values.push(4) 뒤에 println(view.get(0));을 추가해 오류를 확인하세요. owned.into_iter()를 owned.iter()로 바꾸었을 때는 왜 같은 방법으로 상자를 소비할 수 없는지 설명해 보세요.