Go 1.18 Generics의 반공변 유형
Go 1.18에서는 제네릭의 도입으로 반공변 유형에 대한 관심이 촉발되었습니다. 발생하는 주요 질문은 제네릭 컨텍스트 내에서 어떻게 작동하는지입니다.
불리한 동작: 호환되지 않는 유형
다음 코드 조각을 고려하세요.
func Pipe[A, T1, T2 any](left func(A) T1, right func(T1) T2) func(A) T2 { return func(a A) T2 { return right(left(a)) } }
다음과 같이 Pipe를 사용하려고 할 때 함수:
func OpenFile(name string) *os.File { ... } func ReadAll(rdr io.Reader) []byte { ... }
컴파일러가 T1을 io.Reader와 동일하지 않은 *os.File로 처리하기 때문에 컴파일이 실패합니다.
근본 원인: 반공변 의미론
이 문제는 반공변 유형의 특성에서 비롯됩니다. 이 경우 T1은 A보다 더 구체적인 유형일 것으로 예상됩니다. 즉, T1을 허용하는 함수도 A를 허용할 수 있습니다. 그러나 Go 제네릭은 공변 결과 유형을 지원하지 않습니다. 따라서 T1을 반환하는 함수는 암시적으로 변환 가능하더라도 A를 반환할 수 없습니다.
해결 방법 및 결과
현재 Pipe의 서명을 수정할 수 있는 방법은 없습니다. 원하는 동작을 허용하려면 1.18로 이동하세요. 이는 버그로 간주되지 않고 오히려 의도적인 디자인 선택입니다.
해결 방법: 유형 변환
이 제한을 우회하려면 런타임 시 유형 변환을 사용할 수 있습니다.
func Pipe[A, T1, T2, T3 any](left func(A) T1, right func(T2) T3) func(A) T3 { return func(a A) T3 { return right(any(left(a)).(T2)) } }
그러나 이 접근 방식은 컴파일 타임 유형 안전성을 희생합니다.
위 내용은 Go 1.18 Generics에서 반공변 유형은 어떻게 작동합니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!