슬라이스와 이터레이터
선택한 언어나 버전에는 이 주제가 없어 같은 영역의 시작 페이지를 표시합니다.
컬렉션을 함수에 전달하기 전에 원소의 독립 사본이 필요한지, 원본을 잠깐 읽을지, 소유권을 넘길지 정해야 합니다. 이 장은 컬렉션과 소유권을 연결합니다.
사본·뷰·소유권 이동 고르기
섹션 제목: “사본·뷰·소유권 이동 고르기”| 방법 | 원본과의 관계 | 원소 제약 |
|---|---|---|
Vec<T>를 값으로 전달 | 복제 가능한 원소라면 독립 사본, 이동 전용 원소라면 벡터 전체 이동 | 원소 타입에 따라 다름 |
as_slice(), slice(start, end) | 원소를 복사하지 않는 읽기 전용 뷰 | 뷰의 마지막 사용까지 원본 변경·이동 제한 |
.iter() | 원본을 빌려 순회하며 복사·복제한 원소 제공 | 복사·복제 가능한 원소 필요 |
.into_iter() | 벡터 소유권을 가져와 원소를 순서대로 제공 | Box, File 같은 이동 전용 원소도 가능 |
for value in values가 자동으로 벡터 이터레이터를 만들지는 않습니다. 이터레이터 메서드에는 use std.iter;가 필요합니다.
뷰의 마지막 사용과 변환 파이프라인
섹션 제목: “뷰의 마지막 사용과 변환 파이프라인”다음을 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.xenxen run views_and_iterators.xen24681020slice(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으로 확인하세요.
fn main() { let mut values = [1, 2]; let view = values.as_slice(); values.push(3); println(view.get(0));}cannot mutate 'values' while it is borrowedpush 뒤에도 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()로 바꾸었을 때는 왜 같은 방법으로 상자를 소비할 수 없는지 설명해 보세요.