web-dev-qa-db-fra.com

assertion de type golang avec reflect.Typeof ()

J'ai essayé d'identifier une structure avec une valeur de chaîne (nom). reflect.TypeOf renvoie Type.

Mais l'assertion de type nécessite une type.

Comment puis-je transtyper Type à type?

Ou toute suggestion pour le gérer?

http://play.golang.org/p/3PJG3YxIyf

package main

import (
"fmt"
"reflect"
)
type Article struct {
    Id             int64       `json:"id"`
    Title          string      `json:"title",sql:"size:255"`
    Content        string      `json:"content"`
}


func IdentifyItemType(name string) interface{} {
    var item interface{}
    switch name {
    default:
        item = Article{}
    }
    return item
}

func main() {

    i := IdentifyItemType("name")
    item := i.(Article)
    fmt.Printf("Hello, item : %v\n", item)
    item2 := i.(reflect.TypeOf(i))  // reflect.TypeOf(i) is not a type
    fmt.Printf("Hello, item2 : %v\n", item2)

}
12
dorajistyle

Si vous devez activer le type de l'interface externe {}, vous n'aurez pas besoin de réflexion.

switch x.(type){
  case int: 
    dosomething()
}

... mais si vous devez activer le type des attributs dans une interface, procédez comme suit:

s := reflect.ValueOf(x)
for i:=0; i<s.NumValues; i++{
  switch s.Field(i).Interface().(type){
    case int: 
      dosomething()
  }
}

Je n'ai pas trouvé de solution plus propre, j'aimerais savoir si elle existe.

5
Daniel M

Une assertion de type, syntaxiquement, prend un type entre parenthèses, pas une expression. C'est donc une erreur de syntaxe.

Vous semblez essayer de faire une assertion de type avec une valeur calculée au moment de l'exécution. Cela a-t-il du sens? Pensons à ce qu'est une assertion de type.

Une assertion de type comprend deux choses:

  1. Au moment de la compilation: Cela donne à l'expression résultante le type de compilation souhaité. L'expression x.(T) a le type de compilation T. Cela vous permet de remplir l'expression que vous pouvez utiliser avec le type T, ce que vous ne pourrez peut-être pas faire avec le type x.
  2. Au moment de l'exécution: il vérifie si la valeur n'est pas nil et est en fait du type donné; sinon, cela provoque une panique.

La première partie n'a évidemment aucun sens pour un type calculé au moment de l'exécution. Le type de compilation de l'expression obtenue ne peut pas dépendre de quelque chose qui n'est pas connu au moment de la compilation.

La seconde (vérification de l'exécution) peut être effectuée avec un type calculé lors de l'exécution. Quelque chose comme:

if reflect.TypeOf(x) != someTypeComputedAtRuntime {
    panic(42)
}
4
newacct

Je pense que ce que vous recherchez ici est un commutateur de type. https://tour.golang.org/methods/16

2
Nano

Si vous pouvez gérer le bruit et implémenter une méthode supplémentaire que tous les types implémentent, par ex. 'Type () string', vous pouvez faire quelque chose comme ça:

        ve := &ValidationError{}
        nf := &NotFound{}

        switch err.Type() {
        case ve.Type() :
            SendBadRequest(w, err)
        case nf.Type() :
            http.NotFound(w, r)
        default:
            SendInternalError(w, err)
        }
1
rjarmstrong

Je pense que vous pouvez utiliser ValueOf pour résoudre ce problème

item2 :=  reflect.ValueOf(i)
fmt.Printf("Hello, item2 : %v\n", item2)
0
Pedro Fillastre