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