trait 설계

Rust trait 설계 경계

trait는 메서드 묶음이 아니라 타입이 제공해야 할 능력의 계약이며, 정적 디스패치와 동적 디스패치 중 무엇을 원하는지에 따라 형태가 달라진다.

01

능력 정의

Display, Iterator처럼 타입이 제공해야 할 동작을 작게 나눈다.

capability
02

정적/동적 결정

성능과 타입별 최적화가 중요하면 generic, heterogenous collection이면 dyn Trait를 본다.

dispatch
03

관련 타입 선택

Iterator::Item처럼 구현마다 결과 타입이 하나로 정해지면 associated type이 맞다.

associated type
04

object safety 확인

generic method나 Self 반환이 있으면 dyn Trait로 만들 수 있는지 검토한다.

object safe
large trait
구현자가 필요 없는 메서드까지 강제 작은 trait로 나눠 조합하면 테스트와 구현이 쉬워진다.
trait segregation
generic method
object safety 깨짐 dyn Trait가 필요하면 메서드 시그니처에서 타입 매개변수 사용을 조심한다.
vtable limit
associated vs generic
타입 관계 표현 방식 선택 구현당 하나의 Item이면 associated type, 호출마다 바뀌면 generic을 고려한다.
API shape
blanket impl
넓은 구현이 이후 구현을 막음 impl<T> Trait for T 조건이 너무 넓으면 coherence 충돌이 생긴다.
orphan/coherence

API 리뷰 기준

호출자 관점 trait bound가 오류 메시지에서 무엇을 요구하는지 명확해야 한다.
dyn 필요성 서로 다른 구현을 한 컬렉션에 담아야 하는지 먼저 묻는다.
확장성 나중에 메서드를 추가하면 모든 구현자가 깨지는지 고려한다.