상위 트레잇 바운드 (HRTB)
포스트
취소

상위 트레잇 바운드 (HRTB)

개요

들어가기 앞서, 참고로 여기서 for은 반복문 또는 트레잇 구현 키워드가 아닙니다.

여기서 사용된 키워드는 Higher Rank Trait Bounds (HRTB) 키워드입니다.
한국어로 직역하면 상위 트레잇 바운드인데, 일단 이는 잠시 저장해두고 아래의 예제를 보도록 합시다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
trait Foo<F> {
    fn foo(&self, f: F) -> &usize;
}

struct Bar((usize, usize));

impl<T> Foo<T> for Bar
where
    T: Fn(&(usize, usize)) -> &usize,
{
    fn foo(&self, f: T) -> &usize {
        f(&self.0)
    }
}

fn main() {
    let bar = Bar((5, 10));
    let x = bar.foo(|s| &s.0);
    println!("{x}");
}

제네릭 F 타입의 파라미터 f를 갖는 foo를 갖는 트레잇 Foo와,
(usize, usize) 튜플 타입의 튜플을 받는 Bar 구조체가 구현되어있습니다.
아래에서 구현된 제네릭 FFn(&(usize, usize)) -> usize로 트레잇 바운드를 해주었습니다.

foo 함수는 인자 f를 실행하는 고차 함수입니다.
즉, main 함수에서 foo를 호출하여 Bar의 튜플에서 0번째 인덱스의 값을 가져오는 코드입니다.

for 라이프타임

위 코드는 작동엔 문제 없으나, 어떠한 이유에서든 F에 수명을 명시하고 싶을 때가 있습니다.

1
T: <'a> Fn(&'a (usize, usize)) -> &'a usize

하지만 이러한 코드는 작동하지 않습니다. 이럴 때 쓰이는 것이 for<'a>입니다.

1
2
3
4
5
T: for<'a> Fn(&'a (usize, usize)) -> &'a usize

// 또는

for<'a> T: Fn(&'a (usize, usize)) -> &'a usize

놀랍게도 이게 끝입니다. 심지어 Fn 계열 트레잇 외엔 많이 쓰이지도 않습니다.