Languages/RUST
[RUST] TRPL : Chapter 13 - Iterators & Closures
odaebum
2024. 12. 2. 23:26
728x90
Chapter 13 - Iterators & Closures
Closures : 클로저
- 변수에 저장하거나 다른 함수에 인수로 전달할 수 있는 익명 함수. 한 곳에서 클로저를 만든 다음 다른 곳에서 클로저를 호출하여 다른 컨텍스트에서 평가할 수 있다.
- 람다와 비슷함.
장점
- 값을 캡처하면 추가적인 메모리 복사가 발생하지만, 참조로 캡처하면 메모리 사용이 최소화됨.
클로저 유형 추론 및 주석
- 함수와 클로저 사이에는 더 많은 차이점이 있다.
- 클로저 : 일반적으로 함수처럼 매개변수나 반환 값의 유형에 주석을 달 필요가 없다.
- 노출된 인터페이스에서 사용되지 않는다. → 유형 추론
- 한번 호출되어서 유형이 추론된 경우, 다른 유형으로 호출할 수 없다.
- 물론, 명확성을 높이기 위해 유형 주석을 추가할 수 있다. ex → |num: u32|
- 노출된 인터페이스에서 사용되지 않는다. → 유형 추론
- 함수 : 유형 주석은 사용자에게 노출된 명시적 인터페이스의 일부이기 때문에 함수에 필요하다.
- 클로저 : 일반적으로 함수처럼 매개변수나 반환 값의 유형에 주석을 달 필요가 없다.
클로저 환경 챕처 특성이동
FnOnce
: 한 번만 호출할 수 있는 클로저에 적용- 모든 클로저는 최소한 이 특성을 구현
- (&T) → Fn
FnMut
: 캡처된 값을 본문 밖으로 옮기지 않지만 캡처된 값을 변형할 수 있는 클로저에 적용- 두 번 이상 호출이 가능
Fn
: 캡처된 값을 본문에서 옮기지 않고 캡처된 값을 변형하지 않는 클로저와 환경에서 아무것도 캡처하지 않는 클로저에 적용.- 환경을 변형하지 않고도 두 번 이상 호출 가능
- 세 가지 종류의 클로저를 모두 구현할 수 있다.
- 소유권
move
를 통해서 클로저에게 소유권을 부여하는 방식
sort_by_key();
Iterators : 반복자
순회 가능한 값을 하나씩 반환하며, 필요에 따라 반복을 제어할 수 있다.
.next()
: 다음 값을 반환함.- 이때 iter는 가변적으로 만들어야함.
- .next()의 리턴값은 벡터의 값에 대한 불변 참조이다.
반복자는 게으르기 때문에 반복자를 소비해야한다.
let v1: Vec<i32> = vec![1, 2, 3];
//소비하기 위해 _ 연산자 사용
let v2: Vec<_> = v1.iter().map(|x| x + 1).collect();
assert_eq!(v2, vec![2, 3, 4]);
into_iter()
: 기존 iter()는 소유권이 없이 단순한 읽기만 가능하지만, into_iter()는 소유권을 가져온다.- 즉, 기존의 vec값에 접근할 수 없게된다.
루프 vs 반복자
- 반복자 : 고수준 추상화이긴 하지만, 마치 저수준 코드를 직접 작성한 것 처럼 동일한 코드로 컴파일된다.
- Rust의 무비용 추상화로 런타임 오버헤드가 발생하지 않는다.
- C++과 같음.
- 즉, 고수준 저비용으로 루프보다 더 뛰어나다.
→ 모든 계수는 레지스터에 저장되므로 값에 액세스하는 속도가 매우 빠르다. 런타임에 배열 액세스에 대한 경계 검사가 없으므로. ⇒ 모든 최적화는 결과 코드를 매우 효율적으로 만든다.
728x90