Rumah  >  Artikel  >  pembangunan bahagian belakang  >  Bagaimana untuk menentukan sama ada jenis generik adalah "setanding" semasa runtime?

Bagaimana untuk menentukan sama ada jenis generik adalah "setanding" semasa runtime?

WBOY
WBOYke hadapan
2024-02-05 21:54:03574semak imbas

Bagaimana untuk menentukan sama ada jenis generik adalah setanding semasa runtime?

Kandungan soalan

Saya ingin menulis kaedah equals umum yang berfungsi seperti ini:

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")
} 

Untuk ini, saya mencipta antara muka comparable:

type Comparable[T any] interface {
    // Equals returns true if the receiver and the argument are equal.
    Equals(T) bool
}

Saya boleh menyemak sama ada parameter equals melaksanakan antara muka comparable ini seperti ini:

func equals[T any](a, b T) bool {
    aComp, ok := any(a).(Comparable[T])
    if ok {
        return aComp.Equals(b)
    }
    ...

Walau bagaimanapun, setakat ini saya mendapati adalah mustahil untuk mengetahui sama ada a juga memenuhi kekangan a 是否也满足 comparable 约束并将其转换为可以使用 == dan menukarnya kepada sesuatu yang boleh menggunakan ==.

Adakah terdapat cara untuk mengetahui sama ada jenis generik T any adalah T any 在运行时是否是 comparable ,如果是,则使用 == pada masa jalan dan jika ya, gunakan == sebagai perbandingan?

Saya boleh mengehadkan keseluruhan kod saya untuk hanya berfungsi dengan comparable 泛型类型,但我想让用户可以手动添加 equals 方法,如果他们的类型恰好不是 comparable (例如,因为它基于切片) )。


正确答案


如果它使用相等运算符进行编译,则它是可比较的。受 any 约束的类型参数在定义上是不可比较的:它实际上可以是任何内容,包括 func() error jenis generik, tetapi saya mahu membenarkan pengguna menambah kaedah

secara manual jika jenis mereka adalah sesuatu yang lain daripada

(cth. kerana ia berdasarkan kepingan). equals 函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]

Jawapan Betul

Ia adalah setanding jika ia disusun menggunakan operator kesamarataan. Parameter jenis tertakluk kepada mana-mana mengikut takrifannya tidak dapat dibandingkan: ia boleh menjadi hampir apa sahaja, termasuk func() error. Value#Comparable Oleh itu tidak boleh menulis

fungsi menggunakan jenis statik. Anda mesti menggunakan refleksi atau hanya menerima parameter yang melaksanakan antara muka "kesamaan", seperti Comparable[T any] anda sendiri.

ab 具有相同的确切类型,因此 v.Equal(u) 不是毫无意义的,而不是声明 equals(a, b any) Dengan refleksi anda boleh menggunakan

:🎜
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")
}
🎜Dalam kes ini, menggunakan generik mungkin membantu memastikan 🎜 pada masa penyusunan. 🎜 🎜Menggunakan antara muka "equaler", anda mesti menyediakan jenis bernama yang melaksanakannya untuk menukar jenis yang telah diisytiharkan dan memanggil kaedahnya: 🎜
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)
}

Atas ialah kandungan terperinci Bagaimana untuk menentukan sama ada jenis generik adalah "setanding" semasa runtime?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
Artikel ini dikembalikan pada:stackoverflow.com. Jika ada pelanggaran, sila hubungi admin@php.cn Padam