Types 트랙은 많은 걸 못 하는 제네릭 Point<T> 를 남겼어 — 맨 T 는 더하거나 출력 못 해. trait 이 답이야. trait 은 여러 타입이 구현할 수 있는 공유 동작 을 정의하고, Rust 가 다형성을 하는 방식이야.
trait 이 뭐냐
trait 은 타입이 제공하기로 약속하는 메서드 시그니처 묶음이야. Java 나 C# 의 인터페이스를 써봤으면 모양이 익숙해 — 근데 Rust 의 trait 은 더 나아가, 기본 메서드, 제네릭 bound, 연관 타입까지. trait Name { ... } 으로 선언하고, 구현자가 제공해야 할 메서드를 나열해.
trait 구현하기
impl TraitName for TypeName { ... } 는 '이 타입이 이 동작을 제공해' 라고 말해. 한 타입이 여러 trait 을 구현하고; 한 trait 을 여러 타입이 구현해. 그 다대다 그물이 Rust 가 상속 계층 없이 동작을 조합하는 방식이야.
trait 은 공유 데이터가 아니라 공유 동작이야. struct 는 타입이 무엇 인지 말하고 (필드); trait 은 타입이 뭘 할 수 있는지 말해 (메서드). Rust 는 둘을 의도적으로 분리해 — base class 도, 상속 트리도 없이, 그냥 타입이랑 걔들이 옵트인하는 동작뿐.
coherence 규칙
가드레일 하나: trait 이나 타입 중 하나를 네가 소유해야만 그 타입에 trait 을 구현할 수 있어 — 'orphan 규칙'. 두 크레이트가 같은 타입에 같은 trait 을 충돌하게 구현하는 걸 막아. 그래서 외부 trait 을 외부 타입에 구현하려고 가끔 외부 타입을 네 struct 로 감싸 (newtype 패턴).