Interface/Implementation Simultaneity in Golang Generics
Consider the task of creating a generic function to fill a slice with initialized values. While this may seem straightforward, challenges arise when attempting to utilize slices of interfaces and specify concrete types within the function.
In Go 1.18, constraining both X and Y as any types within the generic function Fill leads to a loss of any relationship between the interface and its implementors. This prevents the assignment of instances of Y to slice[i] within the function.
To overcome this, an explicit assertion can be used:
func Fill[X, Y any](slice []X) {
for i := range slice {
slice[i] = any(*new(Y)).(X)
}
}
However, this approach panics when Y does not implement X. Additionally, using a pointer type for Y results in the loss of information about the base type and a nil baseline value.
To address these issues, it is recommended to use a constructor function instead of a second type parameter:
func main() {
xs := make([]sync.Locker, 10)
Fill(xs, func() sync.Locker { return &sync.Mutex{} })
}
func Fill[X any](slice []X, f func() X) {
for i := range slice {
slice[i] = f()
}
}
This approach effectively fills the slice with initialized values created by the constructor function, providing a more robust and flexible solution to the problem.
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