英文:
Interface has no field or method for an exported field in a struct
问题
我有以下结构的代码:
// $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
是公开的?
英文:
I have code that has following structure:
// $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()
}
}
When I do go run main.go
I get following error:
interfaceexport/main.go:13: printer.IsGeneric undefined (type printer.ResourcePrinter has no field or method IsGeneric)
Why do I get above error even though IsGeneric
is exported?
答案1
得分: 12
printer.ResourcePrinter
是一个接口,而不是实际的实例JSONPrinter
,后者可以访问IsGeneric
属性。
你需要在接口中添加一个IsGeneric()
方法(并在JSONPrinter
中实现它),以便能够按照你的需求使用该接口。
参考“golang如何访问接口字段”:你还可以通过类型断言提取接口变量中保存的动态值:
dynamic_value := printer.(JSONPrinter)
然后,dynamic_value
将能够访问IsGeneric
属性。
更多信息请参见“如何访问接口的属性”。
> 即使编译器知道printer.ResourcePrinter
是一个接口,它仍然说IsGeneric
也可能是一个字段。
接口的动态值可以有字段(参见“从接口获取所有字段”)。
当应用于接口时,无字段部分可以指代一个嵌入类型,未限定类型的名称充当字段名。
type ReadWriter interface {
Read(b Buffer) bool
Write(b Buffer) bool
}
type File interface {
ReadWriter // 等同于添加ReadWriter的方法
Locker // 等同于添加Locker的方法
Close()
}
当使用指针指向接口时(当接口本身包含某种指针时),你也会看到这种类型的错误消息:“Go:interface{}
的含义是什么?”和“在Golang中将结构体指针转换为接口指针”。
参见issue 10700。
> 当使用一个新的、不熟悉的包时,程序员有时会错误地使用指向接口类型的指针,而不是直接使用接口类型。
英文:
printer.ResourcePrinter
is an interface, not the actual instance JSONPrinter, which does have access to IsGeneric
You would need to add a method IsGeneric()
to your interface (and implement it in JSONPrinter
) in order to be able to use that interface as you want.
See "golang how to access interface fields": you could also extract the dynamic value held by the interface variable through a type assertion:
dynamic_value := printer.(JSONPrinter)
Then dynamic_value
would have access to the IsGeneric
attribute.
See more at "How to access attribute of interface".
> Even though compiler knows that printer.ResourcePrinter
is an interface, it says that IsGeneric
could also be a field.
The dynamic value of the interface can have field (see "Get all fields from an interface")
The no field part, when applied to an interface, can refer to an embedded type, the unqualified type’s name acts as the field name.
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()
}
You also see that kind of error message when using a pointer to an interface (when the interface itself includes a pointer of sorts: "Go: What's the meaning of interface{}
?" and "Cast a struct pointer to interface pointer in Golang")
See issue 10700
> When using a new, unfamiliar package, programmers occasionally make the error of using a pointer to an interface type instead of the interface type directly.
答案2
得分: 0
简单来说,你的接口没有IsGeneric
方法:
type ResourcePrinter interface {
PrintSomething()
}
英文:
Simple, your interface has no method IsGeneric
:
type ResourcePrinter interface {
PrintSomething()
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论