Go 1.18에서 반공변 유형을 사용하는 제네릭: 설명 및 제한
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)) } }
이 함수는 왼쪽 함수의 출력을 오른쪽 함수로 파이프하여 계산을 연결하는 것을 목표로 합니다. 그러나 다음 예제와 함께 사용하려고 하면
func OpenFile(name string) *os.File { ... } func ReadAll(rdr io.Reader) []byte { ... } var OpenRead = Pipe(OpenFile, ReadAll)
컴파일이 실패합니다. 이는 컴파일러가 T1이 io.Reader와 호환되더라도 *os.File과 동일할 것으로 예상하기 때문입니다. 호환 가능한 유형이 허용될 것으로 기대하는 것이 합리적으로 보일 수 있지만 Go에서는 공변 결과 유형에 대한 지원이 부족하기 때문에 그렇지 않습니다.
Go 1.18에서 이 서명을 수정할 수 있는 방법이 있나요?
아쉽게도 없습니다. Go의 제네릭에는 현재 유형 매개변수를 사용하여 유형 변환성을 표현하는 기능이 부족하여 이 동작을 허용하도록 Pipe 함수를 수정하는 것이 불가능합니다.
이것이 Go 1.18의 버그인가요?
아니요. 공식 FAQ에 명시된 바와 같이 이 동작은 의도적인 것이며 버그로 간주되지 않습니다.
해결 방법
유사한 결과를 얻으려면 변환 단계를 수동으로 구현할 수 있습니다.
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 제네릭이 함수 시그니처의 반공변 유형을 처리할 수 있나요?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!