Golang 1.18 제네릭의 공분산: 한계 이해
Golang 1.18의 제네릭 도입으로 많은 발전이 이루어졌지만 다음과 같은 특정 제한 사항이 남아 있습니다. 완전한 공분산의 부족 support.
문제 이해
두 가지 기능을 사용하는 Pipe라는 일반 함수를 정의하려는 시나리오를 고려해 보세요.
목표는 왼쪽의 출력을 오른쪽의 입력으로 실행하는 함수를 만드는 것입니다. 그러나 경우에 따라 다음 구현이 컴파일에 실패합니다.
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)) } }
이 문제는 Golang 제네릭이 공분산을 완전히 지원하지 않기 때문에 발생합니다. 공분산이란 계약을 위반하지 않고 유형 매개변수를 하위 유형으로 대체할 수 있음을 의미합니다. 이 경우 T1은 하위 유형을 허용하지 않지만 io.ReadCloser는 io.Reader의 하위 유형입니다.
Golang의 디자인 결정
공분산을 완전히 구현하지 않기로 한 Golang의 결정 안전 고려사항을 기반으로 합니다. 공분산을 허용하면 의도한 서명과 일치하지 않는 유형으로 함수가 호출되어 정의되지 않은 동작이 발생하는 상황이 발생할 수 있습니다.
FAQ 설명
Golang FAQ에는 명시적으로 다음과 같은 내용이 나와 있습니다. 현재 동작은 의도적인 것이며 버그가 아닙니다. 이 결정은 애플리케이션 안정성에 해를 끼칠 수 있는 예기치 않은 런타임 오류를 방지하는 것을 목표로 합니다.
변환 유형과 공변 유형
Golang은 전체 공분산을 지원하지 않지만 다음을 허용합니다. 한 유형을 다른 유형으로 변환합니다. 그러나 func Pipe의 경우 유형 매개변수를 사용하여 이 변환을 표현할 방법이 없습니다.
대안으로 left의 결과를 right가 요구하는 유형으로 명시적으로 캐스팅할 수 있습니다. 그러나 이 접근 방식은 다음 수정 코드에서 볼 수 있듯이 컴파일 타임에 유형이 안전하지 않습니다.
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)) } }
이 방법으로 작업을 완료할 수는 있지만 런타임 변환을 위해 컴파일 타임 안전성이 희생됩니다.
위 내용은 Golang 1.18 Generics가 공분산을 완벽하게 지원하지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!