"Effective Go"やその他のQ&Aを読みました。 golangインターフェイスコンプライアンスコンパイルタイプチェック ですが、それでもこの手法の使い方を正しく理解できません。
例をご覧ください:
type Somether interface {
Method() bool
}
type MyType string
func (mt MyType) Method2() bool {
return true
}
func main() {
val := MyType("hello")
//here I want to get bool if my value implements Somether
_, ok := val.(Somether)
//but val must be interface, hm..what if I want explicit type?
//yes, here is another method:
var _ Iface = (*MyType)(nil)
//but it throws compile error
//it would be great if someone explain the notation above, looks weird
}
インターフェイスを実装する場合、値をチェックする単純な方法(たとえば、リフレクションを使用しない)はありますか?
値の型がわからない場合にのみ、値がインターフェイスを実装しているかどうかを確認する必要があります。タイプがわかっている場合、そのチェックはコンパイラによって自動的に行われます。
とにかく本当にチェックしたいのなら、あなたが与えた2番目の方法でそれを行うことができます:
var _ Somether = (*MyType)(nil)
コンパイル時にエラーになります:
prog.go:23: cannot use (*MyType)(nil) (type *MyType) as type Somether in assignment:
*MyType does not implement Somether (missing Method method)
[process exited with non-zero status]
ここでは、MyType
タイプ(およびnil
値)のポインターをSomether
タイプの変数に割り当てていますが、変数名は_
無視されます。
MyType
がSomether
を実装した場合、コンパイルして何もしません
Alphaの上記のソリューションを使用して、さらに削減することもできます。
val:=MyType("hello")
var i interface{}=val
v, ok:=i.(Somether)
に変えることができます:
val := MyType("hello")
v, ok := interface{}(val).(Somether)
1回限りのメソッドをテストする場合は、次のようなこともできます。
val := MyType("hello")
v, ok := interface{}(val).(interface {
Method() bool
})
_reflect.Type
_のImplements(u Type) bool
メソッドを次のように使用することもできます。
_package main
import (
"reflect"
)
type Somether interface {
Method() bool
}
type MyType string
func (mt MyType) Method() bool {
return true
}
func main() {
inter := reflect.TypeOf((*Somether)(nil)).Elem()
if reflect.TypeOf(MyType("")).Implements(inter) {
print("implements")
} else {
print("doesn't")
}
}
_
詳しくは documentation をご覧ください。