[Rust] 동적 디스패치 (번역)
먼저 이전 포스팅을 참조하길 바란다.
https://m.blog.naver.com/sssang97/221681140178
러스트는 트레잇 객체라 불리는 기능을 통해 동적 디스패치를 구현한다.
Foo라는 타입이 있을 경우, &Foo나 Box
트레잇 객체는 포인터를 통해 트레잇을 구현한 구상 타입을 해당 트레잇 타입으로 캐스팅하거나(예: &x as &Foo), 트레잇 타입의 매개변수로 강제전달(coercion)할때 생성된다.
이러한 트레잇 객체의 강제전달(coercions)과 캐스팅은 &mut T -> &mut Foo와, Box
강제전달과 캐스팅은 이런 점에서는 동등하다.
이러한 동작은 포인터의 타입에 대한 컴파일러의 지식을 '지우는' 것처럼 보인다.
이런 이유로 트레잇 객체를 가리켜 '타입 지우개'라고 부르기도 한다.
다시 위의 예제로 돌아가보자. 이제 우리는 트레잇 객체를 얻어서 동적 디스패치를 수행하도록 할 수 있다.
**fn do_something(x: &Foo) **
**{ **
** x.method(); **
**} **
**fn main() **
**{ **
** let x = 5u8; **
** do_something(&x as &Foo); **
**} **
혹은 강제전달로
**fn do_something(x: &Foo) **
**{ **
** x.method(); **
**} **
**fn main() **
**{ **
** let x = "Hello".to_string(); **
** do_something(&x); **
**} **
트레잇 객체를 받는 함수는 Foo를 구현하는 각각의 타입들에 대해서는 알고 있는게 없다.
그래서 정적 디스패치와는 다르게 하나의 복사본만이 생성되고, 대체로 더 적은 코드를 결과로 뱉는다.(아닐수도 있다.)
하지만, 이런저런 추가 비용들이 좀 따른다.
더 느린 가상함수를 호출해야 하고,
함수 인라인이나 관련 최적화들을 억제해야 하기 때문이다.
https://doc.rust-lang.org/1.30.0/book/first-edition/trait-objects.html#representation