"If a worker wants to do his job well, he must first sharpen his tools." - Confucius, "The Analects of Confucius. Lu Linggong"
Front page > Programming > When to Use ~[]E vs []E for Slice Arguments in Go?

When to Use ~[]E vs []E for Slice Arguments in Go?

Published on 2024-11-04
Browse:184

When to Use ~[]E vs []E for Slice Arguments in Go?

Exploring the Subtleties of Generic Slice Arguments

Consider two functions from the experimental slices package: Contains and Grow. Both functions accept slice arguments, but with different type constraints:

Type Constraints

The first argument of Contains has type []E, where E is constrained by comparable, indicating that E must be comparable. On the other hand, the first argument of Grow has type S, constrained by ~[]E, indicating that S must have an underlying type that is a slice of E.

Practical Implications

At first glance, it may seem that there is no practical difference between using these two type constraints. However, this is not the case when you need to return a slice of the same type as the argument in Grow.

The Significance of a Slice-Constrained Type Parameter

If you need to return a slice of the same type as the input argument, you must use a type parameter that itself constrains to a slice (e.g., ~[]E). This allows the function to return a value of the same type as the argument.

A Demonstration with Grow

Let's consider two implementations of Grow:

func Grow[S ~[]E, E any](s S, n int) S // Grow returns a slice of the same type as s
func Grow2[E any](s []E, n int) []E // Grow2 returns a slice of type []E

When passing a slice of a custom type with a slice as its underlying type, Grow can return a value of the same type, while Grow2 cannot. Grow2 can only return a value of an unnamed slice type, []E.

Example

type ints []int // user-defined slice type ints
x := []int{1} // initialize a slice x of type []int
x2 := Grow(x, 10) // x2 will be of type []int
y := ints{1} // initialize a slice y of type ints
y2 := Grow(y, 10) // y2 will be of type ints

Here, Grow2(y, 10) receives a value of type ints but returns a value of type []int, which is not the intended behavior.

Conclusion

In conclusion, when the function call requires returning a slice of the same (possibly named) type as the argument, using a type parameter that itself constrains to a slice (~[]E) is necessary. Otherwise, a type parameter that constrains only the element type (E any) can be used.

Release Statement This article is reprinted at: 1729668019 If there is any infringement, please contact [email protected] to delete it
Latest tutorial More>

Disclaimer: All resources provided are partly from the Internet. If there is any infringement of your copyright or other rights and interests, please explain the detailed reasons and provide proof of copyright or rights and interests and then send it to the email: [email protected] We will handle it for you as soon as possible.

Copyright© 2022 湘ICP备2022001581号-3