2012-05-08 27 views
10

Jak mogę się upewnić, że typ implementuje interfejs podczas kompilacji? Typowym sposobem na to jest brak przypisania do obsługi interfejsów tego typu, jednak mam kilka typów, które są tylko dynamicznie konwertowane. W czasie wykonywania generuje to bardzo mętne komunikaty o błędach, bez lepszej diagnostyki podanej dla błędów kompilacji. Bardzo trudno jest znaleźć w czasie wykonywania, że ​​typy, które spodziewałem się obsługiwać interfejsy, w rzeczywistości nie działają.Upewnij się, że typ implementuje interfejs podczas kompilacji w Go

+0

w jakim języku? – EJP

+0

@EJP: powinno być _go_, język google – themarcuz

Odpowiedz

10

Zakładając, że pytanie dotyczy Go, np.

var _ foo.RequiredInterface = myType{} // or &myType{} or [&]myType if scalar 

jako TLD sprawdzi to za Ciebie w czasie kompilacji.

Edycja: s/[*]/&/

EDIT2: s/obojętne/_/dzięki atom

+4

Możesz napisać '_' zamiast' dummy'. –

+1

Intryguje mnie notacja edycji w stylu sed. – Matt

1

jak poniżej:

http://play.golang.org/p/57Vq0z1hq0

package main 

import(
    "fmt" 
) 

type Test int 

func(t *Test) SayHello() { 
    fmt.Println("Hello"); 
} 

type Saluter interface{ 
    SayHello() 
    SayBye() 
} 

func main() { 
    t := Saluter(new(Test)) 
    t.SayHello() 
} 

przyniesie :

prog.go:19: cannot convert new(Test) (type *Test) to type Saluter: 
    *Test does not implement Saluter (missing SayBye method) 
-3

Nie podoba mi się pomysł popełnienia błędów przez kompilator poprzez umieszczenie linii fikcyjnych w kodzie głównym. To inteligentne rozwiązanie, które działa, ale wolę napisać test do tego celu.

Zakładając, że mamy:

type Intfc interface { Func() } 
type Typ int 
func (t Typ) Func() {} 

Ten test pilnuje Typ realizuje Intfc:

package main 

import (
    "reflect" 
    "testing" 
) 

func TestTypes(t *testing.T) { 
    var interfaces struct { 
     intfc Intfc 
    } 
    var typ Typ 
    v := reflect.ValueOf(interfaces) 
    testType(t, reflect.TypeOf(typ), v.Field(0).Type()) 
} 

// testType checks if type t1 implements interface t2 
func testType(t *testing.T, t1, t2 reflect.Type) { 
    if !t1.Implements(t2) { 
     t.Errorf("%v does not implement %v", t1, t2) 
    } 
} 

Można sprawdzić wszystkich typów interfejsów i dodając je do TestTypes funkcji. Testy pisania dla Go wprowadzono here.

+1

Eh, nie. Zapisywanie przypadków testowych za pomocą refleksji tylko po to, aby uniknąć statycznego sprawdzania kompilatora nie jest zalecane. – zzzz

+0

Co jest nie tak z tym? – Mostafa

+1

Go jest statycznie napisanym językiem. Co jest nie tak ze statycznym sprawdzeniem typu? Dynamiczne sprawdzanie typu jest uzasadnione iff statyczne sprawdzanie typu nie jest możliwe, IMHO. – zzzz

-1
package main 

import (
    "fmt" 
) 

type Sayer interface { 
    Say() 
} 

type Person struct { 
    Name string 
} 

func(this *Person) Say() { 
    fmt.Println("I am", this.Name) 
} 

func main() { 
    person := &Person{"polaris"} 

    Test(person) 
} 

func Test(i interface{}) { 
    //!!here ,judge i implement Sayer 
    if sayer, ok := i.(Sayer); ok { 
     sayer.Say() 
    } 
} 

Przykładowy kod jest tutaj: http://play.golang.org/p/22bgbYVV6q

2

W języku Go nie ma "narzędzia" oświadczenie projektu. Jedyny sposób, aby poprosić kompilator, aby sprawdził, czy typ T implementuje interfejs I, podejmując próbę przypisania (tak, fikcyjny :). Uwaga: Go lang rozróżnia metody zadeklarowane na strukturze i wskaźniku, użyj właściwego w sprawdzaniu przypisania!

type T struct{} 
var _ I = T{}  // Verify that T implements I. 
var _ I = (*T)(nil) // Verify that *T implements I. 

Przeczytaj FAQ dla informacji Why doesn't Go have "implements" declarations?

+0

[http://play.golang.org/p/UNXt7MlmX8] (http://play.golang.org/p/UNXt7MlmX8), aby podświetlić różnicę między sprawdzaniem przydziału wskaźnika i struktury –

Powiązane problemy