154

我刚刚完成Go tour,我对指针和接口感到困惑。为什么这个 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,而且你不需要在变量声明中使用这种类型(参见这个相关问题)。

接口值不是具体结构的值(因为它具有可变大小,这是不可能的),但它是一种指针(更准确地说是指向结构的指针和指向类型的指针)。Russ Cox 在这里准确地描述了它:

接口值表示为两个字对,给出一个指向接口中存储的类型信息的指针和一个指向相关数据的指针。

在此处输入图像描述

这就是为什么Interface,而不是*Interface正确的类型来保存指向实现的结构的指针Interface

所以你必须简单地使用

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
}

编译确定。另请参见此处

于 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{}但实际上我发送的是一个 Struct 指针,它工作正常。

另一个例子在这里

于 2020-01-11T10:38:59.377 回答