2015-01-12 17 views
11

Ho provato a identificare una struttura con valore stringa (nome). reflect.TypeOf restituisce Type.asserzione tipo golang usando reflect.Typeof()

Tuttavia, l'asserzione di tipo deve essere type.

Come posso trasmettere Type a type?

O qualche suggerimento per gestirlo?

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) 

} 
+6

Questo è completamente impossibile in Go.Un'asserzione di tipo asserisce solo un tipo statico fisso con costante di tempo di compilazione. Devi rielaborare la tua soluzione. – Volker

+0

Grazie per il commento. È molto chiaro! – dorajistyle

risposta

4

Un'asserzione di tipo, sintatticamente, accetta un tipo tra parentesi, non un'espressione. Quindi è un errore di sintassi.

Sembra che si stia tentando di eseguire un'asserzione di tipo con un valore calcolato in fase di esecuzione. Ha senso? Pensiamo a cosa sia un'asserzione di tipo.

Un tipo asserzione consiste di due cose:

  1. Al momento della compilazione: provoca l'espressione risultante di avere la fase di compilazione desiderato. L'espressione x.(T) ha il tipo di compilazione T. Questo ti permette di fare le cose che puoi fare con il tipo T, che potresti non essere in grado di fare con il tipo di x.
  2. In fase di esecuzione: Controlla se il valore non è nil ed è effettivamente del tipo specificato e, in caso contrario, causa un panico.

La prima parte ovviamente non ha senso per un tipo calcolato in fase di esecuzione. Il tipo in fase di compilazione dell'espressione risultante non può dipendere da qualcosa che non è noto in fase di compilazione.

Il secondo (controllo di runtime) può essere eseguito con un tipo calcolato in fase di esecuzione. Qualcosa di simile:

5

Se è necessario attivare il tipo di interfaccia esterna {} non è necessario riflettere.

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

... ma se avete bisogno di cambiare il tipo di attributi in un'interfaccia, allora si può fare questo:

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

non ho trovato un modo più pulito, mi piacerebbe amo sapere se esiste.

0

Penso che si possa utilizzare per risolvere questo ValueOf

item2 := reflect.ValueOf(i) 
fmt.Printf("Hello, item2 : %v\n", item2) 
+1

ValueOf() restituisce un tipo reflect.Value non il tipo reale sottostante dell'interfaccia ... – MonkeyButter

1

Se è possibile gestire il rumore e implementare un metodo in più che tutti i tipi implementano esempio 'Type() string', puoi fare qualcosa del genere:

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

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