Why Doesn\'t Golang 1.18 Generics Fully Support Covariance?

Susan Sarandon
Release: 2024-11-17 18:06:02
Original
131 people have browsed it

Why Doesn't Golang 1.18 Generics Fully Support Covariance?

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:

  • left: Accepts an argument of type A and returns a value of type T1.
  • right: Accepts an argument of type T1 and returns a value of type T2.

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))
    }
}
Copy after login

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))
    }
}
Copy after login

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!

source:php.cn
Related Topics
More>
Popular Recommendations
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template