Home >Backend Development >Golang >How Do Contravariant Types Work in Go 1.18 Generics?

How Do Contravariant Types Work in Go 1.18 Generics?

Linda Hamilton
Linda HamiltonOriginal
2024-11-17 15:16:021037browse

How Do Contravariant Types Work in Go 1.18 Generics?

Contravariant Types in Go 1.18 Generics

In Go 1.18, the introduction of generics has sparked interest in contravariant types. A key question that arises is how they function within the context of generics.

Unfavorable Behavior: Incompatible Types

Consider the following code snippet:

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

When attempting to use Pipe with the following functions:

func OpenFile(name string) *os.File { ... }
func ReadAll(rdr io.Reader) []byte { ... }

The compilation fails because the compiler treats T1 as *os.File, which is not identical to io.Reader.

The Root Cause: Contravariant Semantics

The issue stems from the nature of contravariant types. In this case, T1 is expected to be a more specific type than A, meaning functions that accept T1 can also accept A. However, Go generics do not support covariant result types. Thus, Functions that return T1 cannot return A, even if they are implicitly convertible.

Resolution and Consequences

There is currently no way to modify the signature of Pipe in Go 1.18 to allow for the desired behavior. This is not considered a bug but rather an intentional design choice.

Workaround: Type Conversion

To circumvent this limitation, one can resort to type conversion at runtime:

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

However, this approach sacrifices compile-time type safety.

The above is the detailed content of How Do Contravariant Types Work in Go 1.18 Generics?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn