Languages/RUST

[RUST] TRPL : Chapter 13 - Iterators & Closures

odaebum 2024. 12. 2. 23:26
728x90

Chapter 13 - Iterators & Closures

Closures : 클로저

  • 변수에 저장하거나 다른 함수에 인수로 전달할 수 있는 익명 함수. 한 곳에서 클로저를 만든 다음 다른 곳에서 클로저를 호출하여 다른 컨텍스트에서 평가할 수 있다.
  • 람다와 비슷함.

장점

  1. 값을 캡처하면 추가적인 메모리 복사가 발생하지만, 참조로 캡처하면 메모리 사용이 최소화됨.

클로저 유형 추론 및 주석

  • 함수와 클로저 사이에는 더 많은 차이점이 있다.
    • 클로저 : 일반적으로 함수처럼 매개변수나 반환 값의 유형에 주석을 달 필요가 없다.
      • 노출된 인터페이스에서 사용되지 않는다. → 유형 추론
        • 한번 호출되어서 유형이 추론된 경우, 다른 유형으로 호출할 수 없다.
      • 물론, 명확성을 높이기 위해 유형 주석을 추가할 수 있다. ex → |num: u32|
    • 함수 : 유형 주석은 사용자에게 노출된 명시적 인터페이스의 일부이기 때문에 함수에 필요하다.

클로저 환경 챕처 특성이동

  1. FnOnce : 한 번만 호출할 수 있는 클로저에 적용
    • 모든 클로저는 최소한 이 특성을 구현
    • (&T) → Fn
  2. FnMut : 캡처된 값을 본문 밖으로 옮기지 않지만 캡처된 값을 변형할 수 있는 클로저에 적용
    • 두 번 이상 호출이 가능
  3. Fn : 캡처된 값을 본문에서 옮기지 않고 캡처된 값을 변형하지 않는 클로저와 환경에서 아무것도 캡처하지 않는 클로저에 적용.
    • 환경을 변형하지 않고도 두 번 이상 호출 가능
  • 세 가지 종류의 클로저를 모두 구현할 수 있다.
  1. 소유권
    • 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