Убедитесь, что тип реализует интерфейс во время компиляции в Go

Как я могу гарантировать, что тип реализует интерфейс во время компиляции? Типичным способом сделать это является отказ назначить поддержку интерфейсов этого типа, однако у меня есть несколько типов, которые только преобразуются динамически. Во время выполнения это генерирует очень грубые сообщения об ошибках, без лучшей диагностики, заданной для ошибок времени компиляции. Также очень неудобно находить во время выполнения те типы, которые я ожидал поддерживать интерфейсы, на самом деле не так.

Ответ 1

Предполагая, что вопрос касается Go, например

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

поскольку TLD проверит это для вас во время компиляции.

EDIT: s/[*]/&/

EDIT2: s/dummy/_/, благодаря Atom

Ответ 2

В языке Go нет описания " реализует" по дизайну. Единственный способ попросить компилятор проверить, что тип T реализует интерфейс I, пытаясь назначить (да, фиктивный:). Обратите внимание, что Go lang отличает методы, объявленные по структуре и указателю, использует правильный в проверке присваивания!

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

Подробнее прочитайте FAQ Почему у вас нет "объявлений" ?

Ответ 3

Вот так:

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

Уступит:

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

Ответ 4

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

Пример кода приведен здесь: http://play.golang.org/p/22bgbYVV6q

Ответ 5

Мне не нравится идея делать ошибки компилятора, помещая фиктивные строки в основной код. Это умное решение, которое работает, но я предпочитаю писать тест для этой цели.

Предполагая, что имеем:

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

Этот тест гарантирует, что Typ реализует 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)
    }
}

Вы можете проверить все свои типы и интерфейсы, добавив их в функцию TestTypes. Написание тестов для Go вводится здесь.