2012-05-08 7 views
10

¿Cómo puedo garantizar que un tipo implemente una interfaz en tiempo de compilación? La forma típica de hacerlo es no asignar las interfaces de soporte de ese tipo; sin embargo, tengo varios tipos que solo se convierten dinámicamente. En tiempo de ejecución, esto genera mensajes de error muy bruscos, sin los mejores diagnósticos dados para los errores de tiempo de compilación. También es muy inconveniente encontrar en tiempo de ejecución que los tipos que esperaba soportan interfaces, de hecho no.Asegúrese de que un tipo implementa una interfaz en tiempo de compilación en Ir

+0

¿En qué idioma? – EJP

+0

@EJP: debe ser _go_, el idioma de Google – themarcuz

Respuesta

10

Suponiendo que la pregunta es sobre Go, p.

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

como TLD lo comprobará en tiempo de compilación.

EDIT: s/[*]/&/

Edit2: s/maniquí/_ /, gracias Atom

+4

Puede escribir '_' en lugar de' dummy'. –

+1

Estoy intrigado por su notación de edición sed-style. – Matt

1

De esta manera:

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

cederá :

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

No me gusta la idea de hacer errores de lanzamiento del compilador poniendo líneas ficticias en el código principal. Esa es una solución inteligente que funciona, pero prefiero escribir una prueba para este propósito.

Suponiendo que tenemos:

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

Esta prueba se asegura de Typ implementa 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) 
    } 
} 

Puede comprobar todos sus tipos y las interfaces añadiéndolos a TestTypes función. Escritura de pruebas para Go se introduce here.

+1

Eh, no. Escribir un caso de prueba utilizando la reflexión solo para evitar la comprobación estática de un tipo de compilador no es aconsejable. – zzzz

+0

¿Qué pasa con esto? – Mostafa

+1

Go es un lenguaje estáticamente tipado. ¿Qué pasa con una verificación de tipo estática? La verificación dinámica de tipos es razonable si no se puede verificar el tipo estático, en mi humilde opinión. – 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() 
    } 
} 

El ejemplo de código está aquí: http://play.golang.org/p/22bgbYVV6q

2

En el lenguaje Go no hay "implementos" declaración de diseño. La única forma de pedirle al compilador que verifique que el tipo T implementa la interfaz I al intentar una asignación (sí, una ficticia :). Tenga en cuenta que Go lang diferencia los métodos declarados en la estructura y el puntero, , use el derecho en la verificación de asignación.

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

Leer FAQ para más detalles Why doesn't Go have "implements" declarations?

+0

[http://play.golang.org/p/UNXt7MlmX8](http://play.golang.org/p/UNXt7MlmX8) para resaltar la diferencia entre los controles de asignación de puntero y estructura –

Cuestiones relacionadas