Covariance in Golang 1.18 Generics: Understanding Its Limitations
Golang 1.18's introduction of generics brought many advancements, but certain limitations remain, including the lack of complete covariance support.
Understanding the Issue
Consider a scenario where you want to define a generic function called Pipe that takes two functions:
The goal is to create a function that executes the output of left as input to right. However, the following implementation fails to compile in some cases:
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)) } }
This issue arises because Golang generics do not fully supportcovariance. Covariance means that a type parameter can be substituted with a subtype without violating the contract. In this case, T1 does not allow for subtypes while io.ReadCloser is a subtype of io.Reader.
Golang's Design Decision
Golang's decision not to fully implement covariance is based on safety considerations. Permitting covariance could lead to situations where functions are called with types that do not match their intended signatures, resulting in undefined behavior.
FAQ Clarifications
The Golang FAQ explicitly states that the current behavior is intentional and not a bug. This decision aims to prevent unexpected runtime errors that could harm application reliability.
Convertible Types vs. Covariant Types
While Golang does not support full covariance, it allows for the conversion of one type to another. However, in the case of func Pipe, there is no way to represent this conversion using type parameters.
As an alternative, you can explicitly cast the result of left to the type required by right. However, this approach is not type-safe at compile time, as shown in the following modified code:
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)) } }
While this may get the job done, it sacrifices compile-time safety for runtime conversion.
The above is the detailed content of Why Doesn't Golang 1.18 Generics Fully Support Covariance?. For more information, please follow other related articles on the PHP Chinese website!