2017-09-20 5 views
0

Comme l'exemple, puis-je obtenir une valeur nulle de son type sous-jacent à partir de l'interface de travail?obtenir le type sous-jacent à partir d'une interface spécifique dans golang

func MakeSomething(w Worker){ 
    w.Work() 

    //can I get a zeor value type of The type underlying w? 
    //I tried as followed, but failed 

    copy :=w 
    v := reflect.ValueOf(&copy) 
    fm :=v.Elem() 
    modified :=reflect.Zero(fm.Type())//fm.type is Worker, and modified comes to be nil 
    fm.Set(modified) 
    fmt.Println(copy) 
} 

type Worker interface { 
    Work() 
} 

the playground

Répondre

1

Depuis w contient un pointeur vers un Worker, vous pouvez obtenir une valeur nulle de l'élément il pointe. Une fois que vous obtenez l'élément, vous pouvez créer une valeur de ce type zéro:

v := reflect.ValueOf(w).Elem() // Get the element pointed to 
zero := reflect.Zero(v.Type()) // Create the zero value 

Au-dessus de code extrait de panique si vous passez dans un non-pointeur vers MakeSomething. Pour éviter cela, vous pouvez effectuer les opérations suivantes à la place:

v := reflect.ValueOf(w) 
if reflect.TypeOf(w).Kind() == reflect.Ptr { 
    v = v.Elem() 
} 
zero := reflect.Zero(v.Type()) 

Si vous voulez vraiment avoir un pointeur vers une nouvelle Worker, il suffit de remplacer reflect.Zero(v.Type()) avec reflect.New(v.Type()).

+0

ma première question, je vous remercie sincèrement ~ j'ai trouvé la différence, 'fmt.Println (reflect.ValueOf (w) .Type()) // print * main.Testg' ' fmt.Println (reflect.ValueOf (& w) .Type()) // imprimer * main.Worker' dans le cas où j'utilise la deuxième façon (je pense que cela peut changer la valeur w pointer vers) –

+0

@linvan De rien! Oui, '& w' est assez inutile, vraiment. Il vous donnera un pointeur vers une interface contenant un pointeur vers la valeur. Et vous travaillez très rarement (jamais, vraiment) avec des pointeurs vers des interfaces dans Go. – ANisus