2014-07-06 18 views
6

Questo programma non viene compilato:tipo impossibile caso interruttore

package main 

type Validator struct { 
} 

// Error implements error interface 
func (v *Validator) Error() string { 
    return "" 
} 

func test() error { 
    return &Validator{} 
} 

func main() { 
    switch test().(type) { 
    case nil: 
     println("No error") 
    case Validator: 
     println("Validation error") 
     return 
    default: 
     println("Unknown error") 
     return 
    } 
} 

L'errore è:

prog.go:19: impossible type switch case: test() (type error) cannot have dynamic type Validator (missing Error method) 

Ma Validator struttura ha metodo Error.

risposta

8

Si dispone di due tipi diversi, Validator e il tipo di puntatore *Validator e questi due tipi hanno set di metodi diversi.

È stato definito solo un metodo Error() per il puntatore mentre Validator non ha questo metodo.

Che cosa si può fare è la seguente modifica:

// Error implements error interface 
func (v Validator) Error() string { 
    return "" 
} 

...

case *Validator, Validator: // You are actually getting a *Validator 

Questo implementa Error() sia per Validator e *Validator. Come Go specification dice:

Il metodo set di qualsiasi altro tipo T è costituito da tutti i metodi dichiarati con ricevitore tipo T. Il metodo definito del tipo corrispondente puntatore * T è l'insieme di tutti i metodi dichiarati con ricevitore * T o T (cioè, contiene anche il metodo set di T)

+0

Avete qualche consiglio su quando per definire un metodo su un puntatore a oggetto o l'oggetto stesso ? – warvariuc

+1

Definire il metodo su un puntatore quando 1. è necessario modificare l'oggetto. 2. È un grosso oggetto e copiarlo è costoso. – OneOfOne

+0

In questo caso, Validator ha una dimensione pari a 0, quindi è chiaramente meglio usarlo rispetto a un puntatore. –

1

il compilatore è corretta. Il tipo Validator non implementa Error, *Validator fa. Validator e *Validator sono diversi tipi. Basta sostituire il primo con il secondo nel commutatore di tipo:

switch test().(type) { 
case nil: 
    println("No error") 
case *Validator: 
    println("Validation error") 
    return 
default: 
    println("Unknown error") 
    return 
} 

esempio Lavorare on the Go Playground: http://play.golang.org/p/aWqzPXweiA