Rumah > Artikel > pembangunan bahagian belakang > Bagaimana untuk menentukan sama ada jenis generik adalah "setanding" semasa runtime?
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
(cth. kerana ia berdasarkan kepingan). equals
函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]
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
Comparable[T any]
anda sendiri.
a
和 b
具有相同的确切类型,因此 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!