
지그(Zig)에서 런타임 인터페이스와 컴파일 시점 덕 타이핑 사이의 대안으로 트레이트를 활용하는 방법을 소개한다. 트레이트는 특정 타입에 필요한 함수들을 묶은 컴파일 시점 구조체로, 정적 디스패치와 타입별 구현을 명시적으로 유지하는 패턴이다.
글은 런타임 인터페이스가 동적 디스패치에 따른 간접 호출과 최적화 제약을 낳을 수 있고, 컴파일 시점 덕 타이핑은 타입이 따라야 할 계약을 함수 시그니처만으로 분명히 드러내기 어렵다고 설명한다. 트레이트는 필요한 연산을 묶어 함수에 전달하는 방식으로 두 접근의 장점을 조합한다. 예를 들어 덧셈·곱셈·나눗셈 함수를 Num(T) 구조체에 모으면, 뫼비우스 변환 함수가 어떤 수학 연산을 요구하는지 명시할 수 있다. 구현은 컴파일 시점에 처리되므로 컴파일러가 인라인화와 단형화를 적용할 수 있다고 글은 설명한다.
impl 같은 보조 함수로 익명 구조체에서 트레이트 구현을 만들거나, getTrait로 타입에 선언된 구현을 찾을 수도 있다. Into와 From은 타입 변환, Index는 키 기반 접근, Iterator와 Iterable은 반복 처리를 추상화하는 예로 든다. 이런 패턴은 라이브러리나 별도 언어 기능 없이 지그의 컴파일 시점 기능과 타입 리플렉션을 이용해 구성할 수 있다.
다만 트레이트는 관련 타입을 미리 지정해야 하며, 타입 소거와 함께 쓰기 어렵다는 한계가 있다. 컴파일 시점 매개변수마다 별도의 코드가 만들어지고 이를 여러 단계 중첩하면 바이너리 크기가 커지거나 CPU 캐시 부담이 늘어, 상황에 따라 가상 함수 테이블을 쓰는 동적 디스패치보다 느려질 수 있다. 글은 모든 코드를 트레이트로 바꾸기보다, 핫 루프나 구현 세부사항을 추상화해야 하는 함수에서 선택적으로 쓰라고 권한다.
관련 자료: Zig Interfaces, Zig Interface Revisited, Inside Zig's new Writer, Interfaces in Zig, A Practical Guide to Applying Data-Oriented Design, Zig Comptime is Bonkers Good, Rust의 std::ops, Haskell의 Num.
댓글 (0)
로그인하면 이 기사에 내 생각을 남길 수 있어요