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

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

WBOY
Lepaskan: 2024-02-05 21:54:03
ke hadapan
584 orang telah melayarinya

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")
} 
Salin selepas log masuk

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
}
Salin selepas log masuk

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)
    }
    ...
Salin selepas log masuk

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")
}
Salin selepas log masuk
🎜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)
}
Salin selepas log masuk

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!

sumber:stackoverflow.com
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan