首页  >  文章  >  后端开发  >  如何确定泛型类型在运行时是否“可比较”?

如何确定泛型类型在运行时是否“可比较”?

WBOY
WBOY转载
2024-02-05 21:54:03576浏览

如何确定泛型类型在运行时是否“可比较”?

问题内容

我想编写一个通用的 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 是否也满足 a 是否也满足 comparable 约束并将其转换为可以使用 == 约束并将其转换为可以使用 == 的内容。

有没有办法找出泛型类型 T any 在运行时是否是 T any 在运行时是否是 comparable ,如果是,则使用 == ,如果是,则使用 == 进行比较?

我可以限制我的整个代码仅适用于 comparable 泛型类型,但我想让用户可以手动添加 equals 方法,如果他们的类型恰好不是 comparable (例如,因为它基于切片) )。


正确答案


如果它使用相等运算符进行编译,则它是可比较的。受 any 约束的类型参数在定义上是不可比较的:它实际上可以是任何内容,包括 func() error 泛型类型,但我想让用户可以手动添加

方法,如果他们的类型恰好不是

(例如,因为它基于切片) )。equals 函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]

正确答案

如果它使用相等运算符进行编译,则它是可比较的。受 any 约束的类型参数在定义上是不可比较的:它实际上可以是任何内容,包括 func() errorValue#Comparable 因此不可能使用静态类型编写

函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]

ab 具有相同的确切类型,因此 v.Equal(u) 不是毫无意义的,而不是声明 equals(a, b any) 通过反射,您可以使用

:🎜
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")
}
🎜在这种情况下,使用泛型可能有助于在编译时确保 🎜。🎜 🎜使用“equaler”接口,您必须提供实现它的命名类型,以便转换预先声明的类型并调用它们的方法:🎜
func main() {
    fmt.Println(equals(EqualerFloat64(5.57), EqualerFloat64(5.57)))
}

type Equaler[T any] interface {
    Equal(T) bool
}

type EqualerFloat64 float64

func (f EqualerFloat64) Equal(f2 EqualerFloat64) bool {
    return f == f2
}

func equals[T Equaler[T]](a, b T) bool {
    return a.Equal(b)
}

以上是如何确定泛型类型在运行时是否“可比较”?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文转载于:stackoverflow.com。如有侵权,请联系admin@php.cn删除