问题内容
我想编写一个通用的 equals 方法,其工作原理如下:
func equals[T any](a, b T) bool { if hasEqualsMethod(T) { return a.Equals(b) else if isComparable(T) { return a == b } panic("type cannot be compared")}
登录后复制
为此,我创建了一个接口 comparable:
type Comparable[T any] interface { // Equals returns true if the receiver and the argument are equal. Equals(T) bool}
登录后复制
我可以检查 equals 的参数是否实现了这个 comparable 接口,如下所示:
func equals[T any](a, b T) bool { aComp, ok := any(a).(Comparable[T]) if ok { return aComp.Equals(b) } ...
登录后复制
但是,到目前为止,我发现不可能找出 a 是否也满足 comparable 约束并将其转换为可以使用 == 的内容。
有没有办法找出泛型类型 T any 在运行时是否是 comparable ,如果是,则使用 == 进行比较?
我可以限制我的整个代码仅适用于 comparable 泛型类型,但我想让用户可以手动添加 equals 方法,如果他们的类型恰好不是 comparable (例如,因为它基于切片) )。
正确答案
如果它使用相等运算符进行编译,则它是可比较的。受 any 约束的类型参数在定义上是不可比较的:它实际上可以是任何内容,包括 func() error。
因此不可能使用静态类型编写 equals 函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]。
通过反射,您可以使用Value#Comparable:
func equals[T any](a, b T) bool { v := reflect.ValueOf(a) if v.Comparable() { u := reflect.ValueOf(b) return v.Equal(u) } panic("type cannot be compared")}
登录后复制
在这种情况下,使用泛型可能有助于在编译时确保 a 和 b 具有相同的确切类型,因此 v.Equal(u) 不是毫无意义的,而不是声明 equals(a, b any) 。
使用“equaler”接口,您必须提供实现它的命名类型,以便转换预先声明的类型并调用它们的方法:
func main() { fmt.Println(equals(EqualerFloat64(5.57), EqualerFloat64(5.57)))}type Equaler[T any] interface { Equal(T) bool}type EqualerFloat64 float64func (f EqualerFloat64) Equal(f2 EqualerFloat64) bool { return f == f2}func equals[T Equaler[T]](a, b T) bool { return a.Equal(b)}
登录后复制
以上就是如何确定泛型类型在运行时是否“可比较”?的详细内容,更多请关注【创想鸟】其它相关文章!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。
发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2360862.html