douzhang7184
2017-05-20 06:08 阅读 67
已采纳

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

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?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 复制链接分享

2条回答 默认 最新

  • 已采纳
    douyan2680 douyan2680 2017-05-20 06:24

    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.

    点赞 评论 复制链接分享
  • duanjing4623 duanjing4623 2017-05-20 07:53

    Simple, your interface has no method IsGeneric:

    type ResourcePrinter interface {
        PrintSomething()
    }
    
    点赞 评论 复制链接分享

相关推荐