[英]Ensure a type implements an interface at compile time in Go
如何確保類型在編譯時實現接口? 執行此操作的典型方法是無法分配該類型的支持接口,但是我有幾種僅動態轉換的類型。 在運行時,這會生成非常粗魯的錯誤消息,而沒有為編譯時錯誤提供更好的診斷。 在運行時找到我希望支持接口的類型也很不方便,實際上不支持。
假設問題是關於圍棋,例如
var _ foo.RequiredInterface = myType{} // or &myType{} or [&]myType if scalar
因為 TLD 會在編譯時為您檢查。
在 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 了解詳情為什么 Go 沒有“實現”聲明?
通過@smile-on 擴展答案。
在我如何保證我的類型滿足接口? ,這是 Go 作者的常見問題 (FAQ)的一部分,聲明如下:
您可以通過嘗試使用
T
的零值或指向T
指針(視情況而定)來要求編譯器檢查類型T
實現了接口I
我們可以用一個例子來說明這一點:
package main
type I interface{ M() }
type T struct{}
func (T) M() {}
//func (*T) M() {} //var _ I = T{}: T does not implement I (M method has pointer receiver)
func main() {
//avoids allocation of memory
var _ I = T{} // Verify that T implements I.
var _ I = (*T)(nil) // Verify that *T implements I.
//allocation of memory
var _ I = &T{} // Verify that &T implements I.
var _ I = new(T) // Verify that new(T) implements I.
}
如果T
(或*T
,相應地)沒有實現I
,錯誤將在編譯時被捕獲。 請參閱接口實現中的非接口方法。
通常,如果您不知道某個值的類型,則檢查該值是否實現了接口。 如果已知,則檢查由編譯器自動完成。 請參閱檢查值是否實現接口的說明。
空白標識符_
代表變量名,這里不需要它(從而防止“聲明但未使用”錯誤)。 (*T)(nil)
通過將nil
轉換為*T
來創建一個指向T
類型值的未初始化指針。 請參閱理解一段 golang 代碼時遇到問題。
這與例如var t *T
在分配任何內容之前具有的值相同。 請參閱golang 接口合規性編譯類型檢查。 這避免了像使用&T{}
或new(T)
那樣為空結構分配內存。 請參閱理解一段 golang 代碼時遇到問題。
行情編輯以匹配示例。
像這樣:
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)
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
我不喜歡通過在主代碼中放置虛擬行來使編譯器拋出錯誤的想法。 這是一個有效的智能解決方案,但我更喜歡為此目的編寫測試。
假設我們有:
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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.