2014-07-06 31 views
6

Ten program nie kompiluje:typ Impossible przypadek przełącznik

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 
    } 
} 

Błąd jest:

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

Ale Validator struct ma metodę Error.

Odpowiedz

8

Masz dwa różne typy, Validator i typ wskaźnika *Validator, a te dwa typy mają różne zestawy metod.

Użytkownik zdefiniował tylko metodę oznaczania wskaźnika Error(), podczas gdy Validator nie ma tej metody.

Co można zrobić, to następujące zmiany:

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

...

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

ten realizuje Error() zarówno Validator i *Validator. Jak Go specification mówi:

Zestaw metoda jakiegokolwiek innego typu T składa się z wszystkich metod zadeklarowanych w odbiornik typu T. metody określonej odpowiedniego typu wskaźnika * T jest zbiorem wszystkich metod zadeklarowanych z Odbiornik * T lub T (czyli zawiera również zestaw metod T)

+0

Czy macie jakieś porady na temat, kiedy należy określić metodę na wskaźnik do obiektu lub sam obiekt ? – warvariuc

+1

Zdefiniuj metodę na wskaźniku, gdy: 1. musisz zmodyfikować obiekt. 2. Jest to duży obiekt, a jego kopiowanie jest drogie. – OneOfOne

+0

W tym przypadku Validator ma rozmiar 0, więc zdecydowanie lepiej jest użyć go niż wskaźnika. –

1

Kompilator jest poprawny. Validator typ nie implementuje Error, *Validator ma. Validator i *Validator to różne typy. Wystarczy zastąpić były z nią w przełączniku typu:

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

przykład Praca w ruchu Playground: http://play.golang.org/p/aWqzPXweiA