Maison >développement back-end >Golang >Go : Comment spécifier une contrainte de type où le type d'argument de la méthode est le même que le type du récepteur
En langage Go, nous pouvons utiliser des contraintes de type pour spécifier les types de paramètres de fonctions ou de méthodes. Comment spécifier quand nous voulons que le type de paramètre d’une méthode soit le même que le type de récepteur ? Tout d’abord, il doit être clair que le langage Go ne prend pas directement en charge la fonctionnalité selon laquelle le type de paramètre est le même que le type de récepteur. Cependant, nous pouvons obtenir un effet similaire en utilisant des types de pointeurs dans les définitions de méthodes. Ensuite, nous détaillerons comment spécifier le type de paramètre pour qu'il soit le même que le type de récepteur en langage Go.
Je souhaite spécifier une contrainte de type comme indiqué ci-dessous :
type Comparer interface { Compare(another Comparer) int }
Mais je veux que le type d'implémentation passe son propre type concret à la méthode Compare
而不是接口 Comparer
中,如下所示(我知道以下没有实现 Comparer
) :
func (a MyInt) Compare(b MyInt) int { xxxx return xxxx }
J'essaie d'utiliser une interface générique comme celle-ci :
type Comparer[T any] interface { Compare(T) int }
Mais cela n'oblige pas le récepteur de la méthode Compare
à être également de type T.
Existe-t-il un moyen de forcer le type de récepteur et le type de paramètre d'une méthode Compare
à être identiques ?
Lorsque vous parlez de contraintes, vous faites essentiellement référence à une utilisation spécifique d'un type d'interface comme restriction sur l'ensemble des paramètres de type.
Donc, lorsque vous définissez (correctement) l'interface comme :
type Comparer[T any] interface { Compare(T) int }
Vous ne racontez que la moitié de l’histoire. En fait, ce qui précède ne constitue pas une limitation. C'est juste une interface.
Pour être véritablement une contrainte de type, l'interface doit être utilisée comme telle.
func Foo[T Comparer[T]](t1, t2 T) int { return t1.Compare(t2) } type Thing[T Comparer[T]] struct { Value T }
Uniquement dans une liste de paramètres de type, vous pouvez appliquer Compare(T)
的接收者为 T
lui-même en instanciant la contrainte avec ses paramètres de type.
Lorsqu'elle n'est pas utilisée comme contrainte, une interface n'est qu'une définition d'un ensemble de méthodes, by design sans aucune restriction sur les types qui peuvent l'implémenter.
Vous pouvez désormais utiliser des termes de type pour spécifier quels types doivent implémenter une certaine interface. Mais les paramètres de type ne peuvent pas être utilisés directement comme termes de type. Vous devez utiliser un type sans nom, tel qu'un pointeur vers T
:
type Comparer[T any] interface { *T Compare(T) int }
Notez que cela vous oblige à déclarer la méthode sur le récepteur du pointeur, par exemple *MyInt
, qui peut être idéale ou non.
Quoi qu'il en soit, cela ne peut pas être instancié en tant que T Comparer[T]
avec ses propres paramètres de type car la contrainte imposerait un niveau supplémentaire d'indirection de pointeur, peu importe ce que T Comparer[T]
因为无论 T
est. Les paramètres de fonction ne le satisfont jamais.
L'astuce pour réaliser cette fonctionnalité est de l'instancier Comparer
avec différents paramètres de type.
func test[T any, V Comparer[T]](a, b T) int { return V(&a).Compare(b) }
et déclarez la méthode comme :
type MyInt int func (t *MyInt) Compare(other MyInt) int { // implementation }
Cependant, si vous utilisez les contraintes d'interface comme prévu, cette solution de contournement compliquée devient complètement inutile.
Aire de jeuxhttps://www.php.cn/link/3ea816621e0d8ecd5e534ec28051d4d5
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!