传递给object时,一些指针会获得指向其他地址的指针

时间:2017-02-05 08:13:36

标签: pointers go struct interface polymorphism

我正在尝试将一段指针传递给实现接口LogicAdapter的结构。这是我的代码:

main.go:

var adapters[]LogicAdapter
    adapter1 := &ExampleAdapter{}
    fmt.Printf("Addr: %p\n", adapter1)
    adapters = append(adapters, adapter1)
    bot := ChatterBot{"Charlie", MultiLogicAdapter{adapters}}
    bot.getResponse("test", 0)

multiadapterlogic.go:

type MultiLogicAdapter struct {
    adapters []LogicAdapter
}

func (logic *MultiLogicAdapter) process(text string, session int) string {
    //response := logic.adapters[0].process(text, session)
    response := ""
    for _, adapter := range logic.adapters {
        fmt.Printf("Addr: %p\n", &adapter)
    }
    _ = response
    return ""
}

main的输出是:

Addr: 0x5178f0

Addr: 0xc42000a340

我没有包含LogicAdapter,因为我不认为这是必要的。 我不喜欢用很多代码来填充它,但是如果它使事情更容易理解,那么这里是ChatterBot(但请记住bot.getResponse调用process,就是这样)

chatterbot.go

type ChatterBot struct {
    Name string
    MultiLogicAdapter
}

func (bot *ChatterBot) getResponse(text string, session int) string {
    response := bot.process(text, session)
    _ = response
    return ""
}

首先,我想到了以这种方式存储指向LogicAdapters的指针

var adapters[]*LogicAdapter

但每当我尝试在那里插入adapter1指针时,我得到了:

* LogicAdapter是指向接口的指针,而不是接口

所以我发现了this并且学会了这个:

  

当你有一个实现接口的结构时,指向它的指针   struct也自动实现该接口。这就是你的原因   在函数原型中永远不会有* SomeInterface,就像这样   不会向SomeInterface添加任何内容,也不需要这样的类型   在变量声明中(参见此相关问题)。

所以我决定在代码中看到adapters[]声明。问题是,除adapters存储指向adapter1的指针外,当它在MultiLogicAdapter中打印时,它是另一个地址。我知道我将adapters作为副本传递给MultiLogicAdapter,但副本与adapter1具有相同的引用。那么发生了什么?

为什么我在迭代指针?因此:https://www.goinggo.net/2013/09/iterating-over-slices-in-go.html 如果我不这样做,我将创造许多不必要的副本。

1 个答案:

答案 0 :(得分:0)

var adapters []LogicAdapter中,您有一系列接口。接口本身本身就是一个对象,它携带指向你分配给它的对象的指针(有一些额外的信息来跟踪它的类型等)。因此,当您向其附加*ExampleAdapter时,您将创建一个包含指向ExampleAdapter的指针的接口实例。

稍后,当您执行for _, adapter := range logic.adapters {...}时,循环中声明的变量adapter将是切片中“对象”接口的副本。因此,当您使用&adapter获取指针时,您会获得指向接口的指针,而不是指向ExampleAdapter接口包含指针的指针。

有关接口内部的更详细说明,请参阅示例https://research.swtch.com/interfaces