【问题标题】:Interface has no field or method for an exported field in a struct接口在结构中没有用于导出字段的字段或方法
【发布时间】:2017-10-20 07:42:21
【问题描述】:

我的代码具有以下结构:

// $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,我还是会出现上述错误?

【问题讨论】:

    标签: go


    【解决方案1】:

    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”)

    无字段部分,应用于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”)

    issue 10700

    在使用新的、不熟悉的包时,程序员偶尔会犯错误,即使用指向接口类型的指针而不是直接使用接口类型。

    【讨论】:

    • 我认为我对错误消息中的“没有字段”字段部分感到不满。尽管编译器知道 printer.ResourcePrinter 是一个接口,但它说 IsGeneric 也可以是一个字段。 AFAIK 在 Go 中无法为接口定义字段,例如结构。
    【解决方案2】:

    简单,你的界面没有方法IsGeneric

    type ResourcePrinter interface {
        PrintSomething()
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-23
      • 2022-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-26
      • 1970-01-01
      • 2014-08-20
      相关资源
      最近更新 更多