web-dev-qa-db-ja.com

値がインターフェイスを実装しているかどうかの確認の説明

"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
}

インターフェイスを実装する場合、値をチェックする単純な方法(たとえば、リフレクションを使用しない)はありますか?

27

値の型がわからない場合にのみ、値がインターフェイスを実装しているかどうかを確認する必要があります。タイプがわかっている場合、そのチェックはコンパイラによって自動的に行われます。

とにかく本当にチェックしたいのなら、あなたが与えた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タイプの変数に割り当てていますが、変数名は_無視されます。

MyTypeSometherを実装した場合、コンパイルして何もしません

26
Dean Elbaz

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
}) 
0
trevor

_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 をご覧ください。

0
dmigo