golang 中字段的接口

interface for fields in golang

假设我有一个应该用作上传结果的结构:

type uploadResult struct {
  Filename string `json:"filename"`
  Code string `json:"code"`
  Reason string `json:"reason"`
}

还会有其他类似的结构,它们都有一个字段 Code 和另一个名为 Reason 的字段。因此,拥有类似通用接口的东西会很有趣(伪代码;这个不起作用):

type apiResult interface {
  Code string `json:"code"`
  Reason string `json:"reason"`
}

因为我想调用一个提取一些公共字段的函数,但只提取那些公共字段:

func failExit(result apiResult) {
  fmt.Println(result.Reason)
}

那么我该如何重写它才能达到我的预期呢?

此致

您应该能够在特定结构中嵌入具有公共字段的结构。

现场演示: http://play.golang.org/p/7Ju-r-yE1-

type apiResult struct {
  Code string `json:"code"`
  Reason string `json:"reason"`
}

func failExit(result apiResult) {
  fmt.Println(result.Reason)
}

type uploadResult struct {
  Filename string `json:"filename"`
  apiResult // <-- embedded
}

func main() {
  var ul uploadResult
  ul.Code = "...some code..."
  ul.Reason = "The description"
  ul.Filename = "foo.txt"

  failExit(ul.apiResult)
}

所以在这种情况下真的不需要接口。只需将 apiResult 嵌入任何需要它的结构中即可。

长话短说,Go 接口不允许声明字段,因为从概念上讲,它们处理的是行为而不是数据。字段是数据。

有几种方法可以完成您想做的事情:

这里有一些关于如何解决这个问题的例子:

这个使用一个接口来公开 APIResult 字段作为 apiResponse 接口的一部分: http://play.golang.org/p/ONLzvqlP5R

这个使用一个接口将 APIResult 公开为任何包含一个 Result 结构的一部分: http://play.golang.org/p/NzxPHhDls_

关于这一点,您可以通过使用组合来解决此问题,方法是让 APIResponse 成为具有公共字段的结构,然后需要这些字段的任何其他结构导出 APIResponse 结构。

type APIResult struct {
    Code   string `json:"code"`
    Reason string `json:"reason"`
}

type UploadResult struct {
  Filename string `json:"filename"`
  APIResult
}

func failExit(result APIResult) {
  fmt.Println(result.Reason)
}

http://play.golang.org/p/k85vTJoFRn