프로그래밍/Rust
[Rust] 스레드
스레드 이용하기spawn으로 새로운 스레드 생성새로운 스레드를 생성하려면 thread::spawn 함수를 호출하고, 스레드에서 실행하고 싶은 코드가 담긴 클로저를 넘긴다.use std::thread;use std::time::Duration;fn main() { thread::spawn(|| { for i in 1..10 { println!("hi number {} from the spawned thread!", i); thread::sleep(Duration::from_millis(1)); } }); for i in 1..5 { println!("hi number {} from the main thread!",..
[Rust] 스마트 포인터
러스트는 소유권과 대여의 개념을 가지고 있다. 참조자는 데이터를 빌리기만 하는 반면, 스마트 포인터는 가리킨 데이터를 소유한다.Box가장 직관적인 스마트 포인터로, 힙에 데이터를 저장할 수 있게 해준다.fn main() { let b = Box::new(5); println!("b = {}", b);}위와 같이 사용하면 b는 일반적인 코드와 똑같이 5라는 값을 나타낼 것이다. 5가 힙에 할당된다는 점만 다르다.재귀적 타입recursive type은 자기 안에 동일한 타입의 또 다른 값을 담을 수 있다. 컴파일할 때 모든 정보를 알아야 하는 러스트에 있어서 재귀적 타입은 문제를 일으킬 여지가 많다. 박스는 알려진 크기를 갖고 있으므로 박스에 넣으면 이를 허용할 수 있다. 콘스 리스트(cons l..
[Rust] 반복자
반복자반복자는 일련의 아이템을 순서대로 처리할 수 있게 해준다. let v1 = vec![1, 2, 3]; let v1_iter = v1.iter(); for val in v1_iter { println!("Got: {}", val); }반복자를 사용해 for 루프가 호출되면, 반복자의 각 요소가 루프의 한 순번마다 사용된다.Iterator 트레이트모든 반복자는 표준 라이브러리의 Iterator 트레이트를 구현한다.pub trait Iterator { type Item; fn next(&mut self) -> Option;}type Item 과 Self::Item 은 이 트레이트의 연관 타입을 정의한다. 트레이트를 구현하려면 Item 타입도 함께 정의되어야 하..
[Rust] 클로저
러스트는 함수형 언어에 영향을 받아 만들어졌다. 그래서 반복자와 클로저라는 특성을 갖고 있다.클로저클로저는 변수에 저장하거나 다른 함수에 인수로 전달할 수 있는 익명 함수이다. 클로저를 만들고 다른 곳에서 클로저를 호출해 평가할 수 있다. 클로저는 정의된 스코프에서 값을 캡처할 수 있다.클로저로 환경 캡처하기티셔츠 회사에서 메일링 리스트에 있는 사람들에게 한정 티셔츠를 주는 이벤트를 한다. 사람들은 좋아하는 색상을 설정해두면 해당 색상의 티셔츠를 받을 수 있고, 설정을 안 했다면 회사가 가장 많이 보유 중인 색상을 받는다.#[derive(Debug, PartialEq, Copy, Clone)]enum ShirtColor { Red, Blue,}struct Inventory { shirts..
[Rust] 테스트
러스트에서는 함수의 동작을 테스트할 수 있는 문법을 제공한다. 테스트는 cargo test로 실행할 수 있고, 이 명령을 실행하면 테스트 실행 바이너리를 빌드한다.테스트 작성src/lib.rs#[cfg(test]mod tests{ #[test] //이 함수가 테스트 함수임을 명시 fn it_works() { let result = 2 + 2; assert_eq!(result, 4); //result의 값은 4와 같을 것 }}#[test]로 이 함수가 테스트 함수임을 명시한다. assert_eq! 매크로는 ‘result의 값이 4와 같을 것’이라고 단언(assert)한다. cargo test 로 실행하면 test result: ok. 라는 프롬프트가 뜬다.a..
[Rust] 제네릭과 트레이트
제네릭 데이터 타입제네릭을 사용하면 함수 시그니처나 구조체의 아이템에 다양한 데이터 타입을 사용할 수 있다.fn largest(list: &[T]) -> &T { let mut largest = &list[0]; for item in list { if item > largest { largest = item; } } largest}largest 함수는 어떤 타입의 벡터가 들어와도 받아들일 수 있다. 타입 매개변수 T 가 알아서 변신하는 느낌이다.struct Point { x: T, y: T,}fn main() { let integer = Point { x: 5, y: 10 }; let float = Point { x:..
[Rust] 오류 처리
러스트에는 복구 가능한(recoverable) 에러와 복구 불가능한 (unrecoverable) 에러가 있다. recoverable 에러는 Result 타입으로, unrecoverable 에러는 panic! 매크로로 처리한다.panic!코드가 실행되고 문제가 발생했지만 딱히 할 수 있는 일은 없을 수도 있다. 이런 panic 상황이 발생하면 실패 메시지를 출력하고, 되감고(unwind), 스택을 청소하고 종료한다. panic! 매크로를 사용하면 즉시 panic을 발생시킨다.fn main() { panic!("crash!");}//thread 'main' panicked at crashfn main() { let v = vec![1, 2, 3]; v[99];}벡터 크기보다 큰 인덱스에 접근..
[Rust] 컬렉션
컬렉션(collection)은 표준 라이브러리에 포함된 데이터 구조로, 벡터, 문자열과 같이 다수의 값을 담을 수 있으며, 힙에 저장되어 동적으로 할당된다.벡터같은 타입의 값만을 저장하는 구조이다.let v: Vec = Vec::new();let v = vec![1, 2, 3]; 벡터는 제네릭을 이용하여 구현되었다. 따라서 어떤 타입의 값을 저장할 것인지를 angle bracket ‘’으로 감싸서 명시했다(type annotation).초깃값을 함께 지정하는 경우 러스트에서 타입을 유추할 수 있으므로 생략할 수 있다. 이 때는 매크로 vec! 을 사용한다.벡터 활용let mut v = Vec::new();v.push(5);v.push(6);let first = &v[0];let second: Option..