2014-04-19 3 views
10

sto giocando con il tipo di affermazione utilizzando il seguente codice fittizio, e ho ottenuto l'errore:Golang: non si può digitare interruttore sul valore diverso da interfaccia

cannot type switch on non-interface value

Qualcuno sa che cosa significa?

package main 

import "fmt" 
import "strconv" 

type Stringer interface { 
    String() string 
} 

type Number struct { 
    v int 
} 

func (number *Number) String() string { 
    return strconv.Itoa(number.v) 
} 

func main() { 
    n := &Number{1} 
    switch v := n.(type) { 
    case Stringer: 
     fmt.Println("Stringer:", v) 
    default: 
     fmt.Println("Unknown") 
    } 
} 

http://play.golang.org/p/Ti4FG0m1mc

+0

ma quale sarebbe il punto di fare l'asserzione di tipo su un tipo noto? – newacct

+0

@newacct Sì, nel codice di produzione sicuramente non si digita l'asserzione se il tipo è già noto. Il punto di questo esercizio è capire l'asserzione di tipo. – Mingyu

risposta

14

interruttori tipo richiedono un'interfaccia per introspezione. Se stai passando ad un valore di tipo noto, questo esplode. Se si effettua una funzione che accetta un'interfaccia come un parametro, funzionerà:

func typeSwitch(tst interface{}) { 
    switch v := tst.(type) { 
     case Stringer: 
      fmt.Println("Stringer:", v) 
     default: 
      fmt.Println("Unknown") 
    } 
} 

vedere il codice completo qui http://play.golang.org/p/QNyf0eG71_ e la documentazione sulle interfacce golang http://golang.org/doc/effective_go.html#interfaces.

+0

Grazie, @ dethtron5000. Quello che mi mancava era che un cast esplicito per 'interface {}' è richiesto prima del 'type assertion'. – Mingyu

+0

Questa risposta mi ha aiutato enormemente. Sto risolvendo una situazione più complicata con gli switch di tipi di struct, ma questo mi ha spinto in una direzione da wright. Grazie amico. Log in solo per dirti che) – Altenrion

+0

Questa risposta mi ha aiutato enormemente. Sto risolvendo una situazione più complicata con gli switch di tipi di struct, ma questo mi ha spinto in una direzione da wright. Grazie amico. Log in solo per dirvi che) – Altenrion

13

ho capito la risposta, che è quello di lanciare n al interface{} prima del tipo asserzione:

switch v := interface{}(n).(type) 
+0

Non ci sarebbe alcun motivo per usare questo codice nella vita reale, dal momento che qualsiasi variabile non di interfaccia (cioè, 'n') ha già un tipo noto nel codice sorgente che non può cambiare. Ad esempio, se è dichiarato come int, lo sai che è un int comunque. – thomasrutter

0

ci sono conversioni di tipo in Go. Stai facendo una conversione di tipo.