Golang中的字段接口

huangapple go评论69阅读模式
英文:

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 {
  GetCode() string
  GetReason() string
}

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

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

那么,我应该如何重写它以达到我期望的效果呢?

最好的问候。

英文:

Let's say I have a struct which should be used as a result for an upload:

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

There will be other structs like this one, both having a field Code and another one called Reason. It would therefore be interesting to have something like a common interface (pseudo-go-code; this one doesn't work):

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

Because I would like to call a function which extracts some common fields, but only those that are common:

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

So how would I rewrite it so that it does what I'm expecting?

Best regards

答案1

得分: 11

你只需要在特定的结构体中嵌入具有共同字段的结构体即可。

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 // <-- 嵌入
}

func main() {
  var ul uploadResult
  ul.Code = "...一些代码..."
  ul.Reason = "描述"
  ul.Filename = "foo.txt"

  failExit(ul.apiResult)
}

所以在这种情况下,实际上不需要使用接口。只需将apiResult嵌入到需要它的结构体中即可。

英文:

You should just be able to embed a struct with the common fields in the specific structs.

Live demo: http://play.golang.org/p/7Ju-r-yE1-

type apiResult struct {
  Code string `json:&quot;code&quot;`
  Reason string `json:&quot;reason&quot;`
}

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

type uploadResult struct {
  Filename string `json:&quot;filename&quot;`
  apiResult // &lt;-- embedded
}

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

  failExit(ul.apiResult)
}

So there shouldn't really be any need for interfaces in this situation. Just embed the apiResult in whatever structs need it.

答案2

得分: 4

长话短说,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

英文:

Long story short, Go interfaces don't allow fields to be declared because conceptually they deal with behavior not data. Fields are data.

There's a couple of ways to go about what you want to do:

Here's some examples on how to approach this:

This one uses an interface to expose the APIResult fields as part of the apiResponse interface:
http://play.golang.org/p/ONLzvqlP5R

This one uses an interface to expose the APIResult as part of any Result struct that contains one:
http://play.golang.org/p/NzxPHhDls_

On that note, you could solve this by using composition by having APIResponse be a struct that has the common fields and then any other struct that needs those fields exports the APIResponse struct.

type APIResult struct {
    Code   string `json:&quot;code&quot;`
    Reason string `json:&quot;reason&quot;`
}

type UploadResult struct {
  Filename string `json:&quot;filename&quot;`
  APIResult
}

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

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

huangapple
  • 本文由 发表于 2015年3月12日 23:44:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/29014215.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定