>백엔드 개발 >Golang >Go 1.18 Generics에서 'Pipe' 기능이 호환 가능한 유형으로 컴파일되지 않는 이유는 무엇입니까?

Go 1.18 Generics에서 'Pipe' 기능이 호환 가능한 유형으로 컴파일되지 않는 이유는 무엇입니까?

DDD
DDD원래의
2024-11-17 10:30:04506검색

Why Does the `Pipe` Function Fail to Compile with Compatible Types in Go 1.18 Generics?

Go 1.18 제네릭의 반공변 유형 동작

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))
    }
}

이 함수는 left의 출력을 다음과 같이 파이프하도록 설계되었습니다. 오른쪽으로 입력하세요. 그러나 다음과 같이 사용하면 컴파일이 되지 않습니다.

func OpenFile(name string) *os.File {
    ...
}

func ReadAll(rdr io.Reader) []byte {
    ...
}

var OpenRead = Pipe(OpenFile, ReadAll)

컴파일러에서 T1이 io.Reader와 호환됨에도 불구하고 동일하지 않은 *os.File로 판단하기 때문입니다.

원하는 동작은 호환 가능한 유형을 입력으로 받아들이는 함수와 파이프 함수를 연결하는 기능입니다. 이는 제네릭 없이 체인을 호출할 때 예상되는 동작과 일치합니다.

질문:

  1. 파이프 서명을 조정하여 다음을 허용하는 방법이 있습니까? 원하는 동작입니까?
  2. 이 동작은 의도된 것입니까 아니면 버그입니까?

답변:

  1. 아니요, 현재는 없습니다. Go 1.18에서 제네릭을 사용하여 유형 간 호환성을 표현하는 방법입니다.
  2. 이 동작은 버그가 아닙니다. 이는 Go의 공변 결과 유형에 대한 지원 부족을 반영합니다.

해결 방법:

"컴파일 시간 유형 안전을 달성하는 것은 불가능합니다. " 동작이 발생하는 경우 가능한 해결 방법 중 하나는 유형 어설션을 사용하는 것입니다.

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에서 'Pipe' 기능이 호환 가능한 유형으로 컴파일되지 않는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.