Rustlings에서는 standard_library_types에서 Box
와 Arc
, Iterator
를 소개한다.
Box
는 재귀 구조를 가진 타입을 정의할 때 사용되는 타입이다. Rust는 컴파일 타임에 각 타입이 메모리 공간을 얼마나 필요한지 계산한다. 하지만 재귀 구조를 가진 타입은 사용에 따라 필요한 용량이 달라지기 때문에 문제가 발생한다. 그래서 Box
타입이 해당 타입의 포인터 역할을 함으로서 용량 계산 문제를 해결한다.
enum List {
Cons(i32, Box<List>),
Nil,
}
Arc
는 스레드간의 데이터 공유를 안전하게 도와주는 타입이다. 각 스레드는 Arc
의 clone
함수를 통해 같은 데이터에 접근할 수 있고, Arc
는 해당 데이터가 몇번 공유되는지 관리한다.
let some_data = Arc::new(5);
let mut handles = vec![];
for _ in 0..10 {
let data = some_data.clone();
let handle = thread::spawn(move || {
println!("{}", data);
});
handles.push(handle);
}
Iterator
는 collection처럼 여러 데이터를 순서대로 뽑을 수 있는 타입이다. next
함수를 통해 순서대로 데이터를 받는다. 대표적으로 Vec
이나 HashMap
도 Iterator
로 바꿀 수 있다.
let vec = vec![1, 2, 3];
let iterator = vec.iter();
println!("{}", iterator.next());
Iterator
를 만들어내는 함수는 총 3가지가 있다. iter
는 &T를 반환하고, into_iter
는 T를 반환하며, iter_mut
은 &mut T를 반환한다. iter
함수는 값을 참조만 하지만 into_iter
는 소유권 자체를 옮긴다.
let mut vec = vec![1, 2, 3, 4, 5];
let even_vec = vec.into_iter().filter(|x| x % 2 == 0).collect();
Iterator
를 다시 collection 타입으로 바꾸려면 collect
함수를 사용한다. 하지만 Result
타입을 같이 사용하면 반환 방식이 조금 달라진다.
fn result_of_list(list: Vec<Result<i32, String>>) -> Result<Vec<i32>, String> {
list.into_iter().collect()
}
assert_eq!(
result_of_list(vec![Ok(2), Ok(3), Err("butter"), Ok(4)]),
Err("butter")
);
assert_eq!(
result_of_list(vec![Ok(2), Ok(3), Ok(4)]),
Ok(vec![2, 3, 4])
);
'Archive > Rust' 카테고리의 다른 글
[Rustlings] 19. macro (0) | 2021.06.12 |
---|---|
[Rustlings] 18. thread (0) | 2021.06.12 |
[Rustlings] 16. Testing (0) | 2021.06.01 |
[Rustlings] 15. trait (0) | 2021.05.31 |
[Rustlings] 14. Result (0) | 2021.05.30 |