154

Goツアーを行っているところですが、ポインターとインターフェイスについて混乱しています。このGoコードがコンパイルされないのはなぜですか?

package main

type Interface interface {}

type Struct struct {}

func main() {
    var ps *Struct
    var pi *Interface
    pi = ps

    _, _ = pi, ps
}

つまり、Structがである場合Interface、なぜではないのでしょう*Struct*Interface

私が受け取るエラーメッセージは次のとおりです。

prog.go:10: cannot use ps (type *Struct) as type *Interface in assignment:
        *Interface is pointer to interface, not interface
4

4 に答える 4

213

インターフェイスを実装する構造体がある場合、その構造体へのポインタもそのインターフェイスを自動的に実装します。そのため*SomeInterface、関数のプロトタイプには何も追加されSomeInterfaceないため、変数宣言にそのような型は必要ありません(この関連する質問を参照してください)。

インターフェイス値は具体的な構造体の値ではありませんが(サイズが可変であるため、これは不可能です)、一種のポインターです(より正確には、構造体へのポインターと型へのポインターです)。 )。ラスコックスはそれを正確にここで説明しています:

インターフェイス値は、インターフェイスに格納されているタイプに関する情報へのポインタと、関連するデータへのポインタを提供する2ワードのペアとして表されます。

ここに画像の説明を入力してください

これが、を実装する構造体へのポインタを保持するための正しい型ではInterfaceなく、である理由です。*InterfaceInterface

だからあなたは単に使用する必要があります

var pi Interface
于 2012-11-22T11:31:30.873 に答える
9

これはおそらくあなたが意味したことです:

package main

type Interface interface{}

type Struct struct{}

func main() {
        var ps *Struct
        var pi *Interface
        pi = new(Interface)
        *pi = ps

        _, _ = pi, ps
}

OKをコンパイルします。こちらもご覧ください

于 2012-11-22T11:20:04.647 に答える
0

構造体をインターフェースに割り当てる非常に簡単な方法は次のとおりです。

package main

type Interface interface{}

type Struct struct{}

func main() {
    ps := new(Struct)
    pi := Interface(ps)

    _, _ = pi, ps
}

https://play.golang.org/p/BRTaTA5AG0S

于 2018-12-27T23:42:05.423 に答える
0

interface{}引数として消費している間、次の方法を使用していますが、以下に示すようeventsI interface{}に、構造体ポインターを送信することはできます。

func Wait(seconds float64) *WaitEvent {
    return WaitEventCreate(seconds)
}

main.go

var introScene = []interface{}{
        storyboard.Wait(5),
        storyboard.Wait(2),
    }

    var storyboardI = storyboard.Create(stack, introScene)
    stack.Push(&storyboardI)

storyboard.goファイル作成関数内にあります

type Storyboard struct {
    Stack  *gui.StateStack
    Events []interface{} //always keep as last args
}

func Create(stack *gui.StateStack, eventsI interface{}) Storyboard {
    sb := Storyboard{
        Stack: stack,
    }

    if eventsI != nil {
        events := reflect.ValueOf(eventsI)
        if events.Len() > 0 {
            sb.Events = make([]interface{}, events.Len())
            for i := 0; i < events.Len(); i++ {
                sb.Events[i] = events.Index(i).Interface()
            }
        }
    }

    return sb
}

上記のように、Storyboard.goは消費していますEvents []interface{}が、実際にはIm送信はStructポインターであり、正常に機能します。

ここにもう1つの例

于 2020-01-11T10:38:59.377 に答える