接口没有结构中导出字段的字段或方法

时间:2017-05-20 06:08:59

标签: go

我的代码具有以下结构:

// $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,为什么会出现上述错误?

2 个答案:

答案 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()
}