web-dev-qa-db-fra.com

Explication de la vérification si la valeur implémente l'interface

J'ai lu "Go efficace" et d'autres questions et réponses comme celle-ci: vérification du type de compilation de la conformité de l'interface golang , mais néanmoins je ne comprends pas correctement comment utiliser cette technique.

Veuillez voir l'exemple:

type Somether interface {
    Method() bool
}

type MyType string

func (mt MyType) Method2() bool {
    return true
}

func main() {
    val := MyType("hello")

    //here I want to get bool if my value implements Somether
    _, ok := val.(Somether)
    //but val must be interface, hm..what if I want explicit type?

    //yes, here is another method:
    var _ Iface = (*MyType)(nil)
    //but it throws compile error
    //it would be great if someone explain the notation above, looks weird
}

Existe-t-il des moyens simples (par exemple sans utiliser de réflexion) de vérifier la valeur s’il implémente une interface?

27

Vous n'avez qu'à vérifier si une valeur implémente une interface si vous ne connaissez pas le type de la valeur. Si le type est connu, cette vérification est effectuée automatiquement par le compilateur.

Si vous voulez vraiment vérifier de toute façon, vous pouvez le faire avec la deuxième méthode que vous avez donnée:

var _ Somether = (*MyType)(nil)

ce qui entraînerait une erreur au moment de la compilation:

prog.go:23: cannot use (*MyType)(nil) (type *MyType) as type Somether in assignment:
    *MyType does not implement Somether (missing Method method)
 [process exited with non-zero status]

Ce que vous faites ici, c'est d'affecter un pointeur de type MyType (et de la valeur nil) à une variable de type Somether, mais puisque le nom de la variable est _ il est ignoré.

Si MyType implémentait Somether, il compilerait et ne ferait rien

26
Dean Elbaz

Vous pouvez également prendre la solution ci-dessus d'Alpha et la réduire davantage:

val:=MyType("hello")
var i interface{}=val
v, ok:=i.(Somether)

peut être transformé en:

val := MyType("hello")
v, ok := interface{}(val).(Somether)

Si vous essayez de tester des méthodes ponctuelles, vous pouvez même faire quelque chose comme:

val := MyType("hello")
v, ok := interface{}(val).(interface {
    Method() bool
}) 
0
trevor

Il est également possible d'utiliser la méthode Implements(u Type) bool de reflect.Type de la manière suivante:

package main

import (
    "reflect"
)

type Somether interface {
    Method() bool
}

type MyType string

func (mt MyType) Method() bool {
    return true
}

func main() {

    inter := reflect.TypeOf((*Somether)(nil)).Elem()

    if reflect.TypeOf(MyType("")).Implements(inter) {
        print("implements")
    } else {
        print("doesn't")
    }
}

Vous pouvez en savoir plus à ce sujet dans la documentation .

0
dmigo