Maison >développement back-end >Golang >Comment déterminer si un type générique est « comparable » au moment de l'exécution ?

Comment déterminer si un type générique est « comparable » au moment de l'exécution ?

WBOY
WBOYavant
2024-02-05 21:54:03589parcourir

Comment déterminer si un type générique est « comparable » au moment de lexécution ?

Contenu de la question

Je souhaite écrire une méthode equals générale qui fonctionne comme ceci :

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

Pour cela, j'ai créé une interface comparable :

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

Je peux vérifier si le paramètre égal à implémente cette comparable interface comme celle-ci :

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

Cependant, jusqu'à présent, j'ai trouvé impossible de savoir si a satisfait également à la contrainte a 是否也满足 comparable 约束并将其转换为可以使用 == et de le convertir en quelque chose qui puisse utiliser ==.

Existe-t-il un moyen de savoir si un type générique T any est T any 在运行时是否是 comparable ,如果是,则使用 == au moment de l'exécution, et si oui, utiliser == pour comparaison ?

Je pourrais restreindre l'intégralité de mon code pour qu'il ne fonctionne qu'avec comparable 泛型类型,但我想让用户可以手动添加 equals 方法,如果他们的类型恰好不是 comparable (例如,因为它基于切片) )。


正确答案


如果它使用相等运算符进行编译,则它是可比较的。受 any 约束的类型参数在定义上是不可比较的:它实际上可以是任何内容,包括 func() error types génériques, mais je souhaite permettre aux utilisateurs d'ajouter manuellement

méthodes si leur type s'avère être autre chose que

(par exemple parce qu'il est basé sur des tranches). equals 函数。您必须使用反射或仅接受实现“相等”接口的参数,例如您自己的 Comparable[T any]

Bonne réponse

Elle est comparable si elle est compilée en utilisant l'opérateur d'égalité. Un paramètre de type soumis à any est par définition incomparable : il peut s'agir de pratiquement n'importe quoi, y compris une func() error. Value#Comparable Il est donc impossible d'écrire

des fonctions en utilisant des types statiques. Vous devez utiliser la réflexion ou accepter uniquement les paramètres qui implémentent une interface « d'égalité », comme votre propre Comparable[T any].

ab 具有相同的确切类型,因此 v.Equal(u) 不是毫无意义的,而不是声明 equals(a, b any) Avec réflexion, vous pouvez utiliser

 :🎜
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")
}
🎜Dans ce cas, l'utilisation de génériques peut aider à garantir 🎜 au moment de la compilation. 🎜 🎜À l'aide de l'interface "equaler", vous devez fournir un type nommé qui l'implémente afin de convertir les types pré-déclarés et appeler leurs méthodes : 🎜
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)
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer