우리 집에도 Traits는 있다: Zig에서 구현하는 컴파일 타임 타입 계약

1 week ago 12

Zig의 컴파일 타임 구조체에 특정 타입의 관련 함수를 묶으면, 별도 라이브러리나 언어 기능 없이 명시적인 타입 계약을 갖춘 Trait 패턴을 구현할 수 있음 기존 동적 인터페이스는 메서드 시그니처를 보장하지만 최적화를 제한하고, comptime 덕 타이핑은 정적 최적화에 유리하지만 호출자와 구현자가 타입 요구사항을 문서화하고 지켜야 함 Trait는 필요한 연산을 컴파일 타임에 전달하는 의존성 주입 방식으로, 계약을 명확히 하면서 컴파일러의 단형화와 인라이닝을 허용함 impl, getTrait 같은 도우미와 Trait 펑터로 구현 생성과 전달을 간소화할 수 있지만, 대상 타입을 미리 알아야 하므로 타입 소거와는 잘 맞지 않음 핫 루프의 정적 추상화에 유용하지만 모든 코드를 바꿀 패턴은 아님. 컴파일 타임 매개변수의 조합이 늘면 바이너리 크기와 캐시 부담 때문에 동적 디스패치보다 느려질 수도 있음 Zig의 두 가지 다형성과 Trait의 위치 Zig 0.17을 기준으로, 일반적인 다형성 구현은 두 가지 방식으로 나뉨 동적 인터페이스는 불투명 포인터, 가상 함수 테이블, 동적 디스패치로 런타임 다형성을 구현함 comptime 덕 타이핑은 타입 리플렉션, switch, 컴파일 타임 단형화로 정적 다형성을 구현함 인터페이스는 Zig의 언어 기능은 아니지만 런타임 다형성을 구현하는 사실상의 방식임 함수는 메서드 시그니처를 보장받지만 구현 자체는 알지 못함 런타임 모듈성과 간접 참조가 컴파일러의 최적화를 제한하고 성능 비용을 발생시킴 comptime 덕 타이핑은 anytype이나 타입 매개변수 T를 받고, 리플렉션 또는 필요한 메서드에 대한 가정으로 구현함 C++ 템플릿이나 C 매크로와 유사하게 코드를 단형화할 수 있음 계약 위반은 런타임이 아니라 컴파일 타임에 발견되지만, 허용하는 타입의 계약을 문서화하고 따를 책임은 남음 Trait는 특정 타입에 대한 관련 함수를 담은 컴파일 타임 구조체임 Rust의 Trait나 Haskell의 타입클래스와 유사한 추상화를 Zig 사용자 코드의 관례로 구현함 직접적인 영감은 OCaml 모듈에서 얻었으며, Zig에서 모듈은 이미 다른 의미이므로 Trait라는 이름을 사용함 가상 함수 테이블처럼 하위 작업의 실행 방법을 전달하되 런타임이 아닌 컴파일 타임에 평가함 Reducer로 보는 기본 형태 Reducer(T) 는 초기값 empty: T와 결합 함수 combine: fn(T, T) T를...

Read Entire Article




피플앤툴즈 네트워크
🛍 샵