【问题标题】:Go: Pointer to type is incompatible with interfaceGo:指向类型的指针与接口不兼容
【发布时间】:2018-02-17 20:42:11
【问题描述】:

我不确定如何正确地提出问题。我有 2 个 go 代码 sn-ps 应该做完全相同的事情,但显然它们没有,因为一个有效,另一个无效(不编译)

func writeSomething(writer *io.Writer) {
}

func main() {
    file, _ := os.Create("error.log")
    var logWriter io.Writer = file
    writeSomething(&logWriter)

}

func main2() {
    file, _ := os.Create("error.log")
    writeSomething(&file)

}

Playground

main() 有效,而 main2() 无效。

prog.go:20:17: 不能在 writeSomething 的参数中使用 &file (type **os.File) 作为 type *io.Writer: *io.Writer 是指向接口的指针,不是接口

唯一的区别是我使用了一个中间变量,但我没有做任何指针引用或取消引用。

我在这里做错了什么?

【问题讨论】:

  • 错误信息是准确的。只需删除函数签名 func writeSomething(writer io.Writer) 中的间接性,无论如何都不需要
  • 好的,谢谢,这行得通。但我仍然会感兴趣为什么第一个版本可以工作,即使它做了同样的事情
  • main 中,您将file 转换为接口io.Writer,然后传递writeSomething 指向接口的指针,这正是writeSomething 所期望的。
  • main2 中有一个指向os.File 的指针,然后将指向该指针的指针传递给writeSomething。 Go 无法将其转换为指向接口 io.Writer 的指针。

标签: go


【解决方案1】:

您不应该使用指向接口的指针,这在 Go 中是一种不好的做法。
关于无法编译的代码 - 当您创建一个中间变量 logWriter 时,您分配了一个接口变量,它有自己分配的内存来描述它存储的内容(实际类型)和对实际结构的引用。
这就是&logWriter&file 具有不同类型的原因。
但正如我之前伤心的那样,你不应该使用指向接口的指针,只使用接口类型,不要获取接口类型变量的地址。

【讨论】:

  • 好的,谢谢你的解释。我显然还没有完全理解 go 中的接口是如何工作的。来自 C++ 和 Java 类型的 io.Writer 看起来确实很像一个对象,我不想通过值传递它。
猜你喜欢
  • 2020-10-11
  • 2014-02-16
  • 2017-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多