英文:
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:"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)
}
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:"code"`
Reason string `json:"reason"`
}
type UploadResult struct {
Filename string `json:"filename"`
APIResult
}
func failExit(result APIResult) {
fmt.Println(result.Reason)
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论