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

Was*_*eem 2 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()
  }
}
Run Code Online (Sandbox Code Playgroud)

当我这样做时,go run main.go我得到以下错误:

interfaceexport/main.go:13: printer.IsGeneric undefined (type printer.ResourcePrinter has no field or method IsGeneric)

为什么即使IsGeneric导出也会出现上述错误?

Von*_*onC 8

printer.ResourcePrinter 是一个接口,而不是实际的JSONPrinter实例,它可以访问IsGeneric

您需要向IsGeneric()接口添加一个方法(并在其中实现JSONPrinter),以便能够根据需要使用该接口.

请参阅" golang如何访问接口字段 ":您还可以通过类型断言提取接口变量所拥有的动态值:

dynamic_value := printer.(JSONPrinter)
Run Code Online (Sandbox Code Playgroud)

然后dynamic_value可以访问该IsGeneric属性.

有关详细信息,请参阅" 如何访问界面属性 ".


尽管编译器知道这printer.ResourcePrinter是一个接口,但它说它也IsGeneric可能是一个字段.

接口的动态值可以包含字段(请参阅" 从接口获取所有字段 ")

应用于接口时,no字段部分可以引用嵌入类型,非限定类型的名称作为字段名称.

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()
}
Run Code Online (Sandbox Code Playgroud)

使用指向接口的指针时也会看到这种错误消息(当接口本身包含一个指针时:" Go:含义是interface{}什么? "和" 在Golang中向接口指针强制转换结构指针 ")

问题10700

当使用新的,不熟悉的包时,程序员偶尔会出现使用指向接口类型的指针而不是直接使用接口类型的错误.