Recursive Type Constraint with Predefined Type
In Go generics, it is possible to specify type constraints on generic types using interfaces. However, it can be challenging to define a constraint that requires the implementation of a method with an argument of the generic type itself.
The current draft of Go generics does not allow recursive type constraints, making it impossible to achieve the desired behavior. For example, consider the following interface:
type Lesser interface { Less(rhs Lesser) bool }
We can implement this interface for a custom type, such as Int:
type Int int func (lhs Int) Less(rhs Int) bool { return lhs < rhs }
However, the following code will fail to compile because Int does not satisfy the Lesser interface:
func IsLess[T Lesser](lhs, rhs T) bool { return lhs.Less(rhs) } func main() { IsLess[Int](Int(10), Int(20)) }
A workaround for this limitation is to define a generic interface that references itself as a type parameter:
type Lesser[T any] interface { Less(T) bool }
This interface specifies that any type that implements the Lesser interface must have a Less method that takes an argument of the same type.
We can then define the IsLess function using this generic interface:
func IsLess[T Lesser[T]](x, y T) bool { return x.Less(y) }
Now, we can implement custom types that fulfill the Lesser constraint:
type Apple int func (a Apple) Less(other Apple) bool { return a < other } type Orange int func (o Orange) Less(other Orange) bool { return o < other }
Using the IsLess function with these custom types will result in correct behavior:
func main() { fmt.Println(IsLess(Apple(10), Apple(20))) // true fmt.Println(IsLess(Orange(30), Orange(15))) // false }
This solution effectively enforces the recursive type constraint by requiring the implementation of a method with an argument of the generic type.
The above is the detailed content of How Can I Achieve Recursive Type Constraints in Go Generics?. For more information, please follow other related articles on the PHP Chinese website!