for<'a> (상위 트레잇 바운드 HRTB)
들어가기 앞서, 참고로 여기서 for
은 반복문 또는 트레잇 구현 키워드가 아닙니다.
Higher Rank Trait Bounds
(HRTB
) 키워드입니다.
한국어로 직역하면 상위 트레잇 바운드인데, 일단 이는 잠시 저장해두고 아래의 예제를 보도록 합시다.
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
구조체가 구현되어있습니다.
아래에서 구현된 제네릭 F
는 Fn(&(usize, usize)) -> usize
로 트레잇 바운드를 해주었습니다.
foo
함수는 인자 f
를 실행하는 고차 함수입니다.
즉, main
함수에서 foo
를 호출하여 Bar
의 튜플에서 0
번째 인덱스의 값을 가져오는 코드입니다.
for 라이프타임
위 코드는 작동엔 문제 없으나, 어떠한 이유에서든 F
에 수명을 명시하고 싶을 때가 있습니다.
#![allow(unused)] fn main() { T: <'a> Fn(&'a (usize, usize)) -> &'a usize }
하지만 이러한 코드는 작동하지 않습니다. 이럴 때 쓰이는 것이 for<'a>
입니다.
#![allow(unused)] fn main() { T: for<'a> Fn(&'a (usize, usize)) -> &'a usize // 또는 for<'a> T: Fn(&'a (usize, usize)) -> &'a usize }
놀랍게도 이게 끝입니다. 심지어 Fn
계열 트레잇 외엔 많이 쓰이지도 않습니다.