Archive/Rust

[Rustlings] 17. Standard Library Types

Rustlings에서는 standard_library_types에서 BoxArc, Iterator를 소개한다.

 

Box는 재귀 구조를 가진 타입을 정의할 때 사용되는 타입이다. Rust는 컴파일 타임에 각 타입이 메모리 공간을 얼마나 필요한지 계산한다. 하지만 재귀 구조를 가진 타입은 사용에 따라 필요한 용량이 달라지기 때문에 문제가 발생한다. 그래서 Box 타입이 해당 타입의 포인터 역할을 함으로서 용량 계산 문제를 해결한다.

enum List {
  Cons(i32, Box<List>),
  Nil,
}

Arc는 스레드간의 데이터 공유를 안전하게 도와주는 타입이다. 각 스레드는 Arcclone 함수를 통해 같은 데이터에 접근할 수 있고, 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이나 HashMapIterator로 바꿀 수 있다.

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