Go 1.18 제네릭이 함수 시그니처의 반공변 유형을 처리할 수 있나요?

Susan Sarandon
풀어 주다: 2024-11-17 10:50:02
원래의
1003명이 탐색했습니다.

Can Go 1.18 Generics Handle Contravariant Types in Function Signatures?

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 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿