我的代码具有以下结构:
// $GOPATH/experiments/interfaceexport/printer/printer.go
package printer
import "fmt"
type ResourcePrinter interface {
PrintSomething()
}
type JSONPrinter struct {
IsGeneric bool
}
func (printer *JSONPrinter) PrintSomething() {
fmt.Println("JSON")
}
// $GOPATH/experiments/interfaceexporter/printerretriever/printerretriever.go
package printer
import "experiments/interfaceexporter/printer"
func GetPrinter() printer.ResourcePrinter {
return &printer.JSONPrinter{IsGeneric: true}
}
// $GOPATH/experiments/interfaceexport/main.go
import "experiments/intefaceexport/printerretriever"
func main() {
printer := printerretriever.GetPrinter()
printer.PrintSomething() // "JSON"
// interfaceexport/main.go:13: printer.IsGeneric undefined (type printer.ResourcePrinter has no field or method IsGeneric)
if printer.IsGeneric {
printer.PrintSomething()
}
}
当我go run main.go
时,我收到以下错误:
interfaceexport/main.go:13: printer.IsGeneric undefined (type printer.ResourcePrinter has no field or method IsGeneric)
即使导出IsGeneric
,为什么会出现上述错误?
答案 0 :(得分:7)
printer.ResourcePrinter
是一个接口,而不是实际的JSONPrinter实例,它可以访问IsGeneric
您需要在接口中添加方法IsGeneric()
(并在JSONPrinter
中实现),以便能够根据需要使用该接口。
请参阅" golang how to access interface fields":您还可以通过类型断言提取接口变量所拥有的动态值:
dynamic_value := printer.(JSONPrinter)
然后dynamic_value
可以访问IsGeneric
属性。
请参阅" How to access attribute of interface"。
尽管编译器知道
printer.ResourcePrinter
是一个接口,但它说IsGeneric
也可以是一个字段。
界面的动态值可以包含字段(请参阅" Get all fields from an interface")
no字段部分在应用于an interface时可以引用嵌入类型,非限定类型的名称作为字段名称。
type ReadWriter interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type File interface {
ReadWriter // same as adding the methods of ReadWriter
Locker // same as adding the methods of Locker
Close()
}
当对接口使用指针时,也会看到这种错误消息(当接口本身包含各种指针时:" Go: What's the meaning of interface{}
?"并且" Cast a struct pointer to interface pointer in Golang&#34)
请参阅issue 10700
当使用一个新的,不熟悉的包时,程序员偶尔会出现使用指向接口类型的指针而不是直接使用接口类型的错误。
答案 1 :(得分:0)
简单,您的界面没有方法IsGeneric
:
type ResourcePrinter interface {
PrintSomething()
}