英文:
Golang base struct to define methods in substructs
问题
我想创建一个基本结构体,其中包含两个方法,我希望在子结构体中使用这些方法。例如:
type Base struct {
Type string `json:"$type"`
}
func (b Base) GetJSON() ([]byte, error) {
return json.Marshal(b)
}
func (b Base) SetType(typeStr string) interface{} {
b.Type = typeStr
return b
}
在新的结构体中,我想这样使用它:
type Auth struct {
Base
Username string
Password string
}
并在主函数中调用这些方法:
func main() {
a := Auth{
Username: "Test",
Password: "test",
}
a = a.SetType("testtype").(Auth)
j, _ := a.GetJSON()
}
在SetType方法中,我得到了一个由于接口类型不是Auth
类型而引发的恐慌,而是Base
类型。
在GetJSON方法中,我得到了一个关于Type的JSON,但只有Type字段。
有没有解决我想解决的问题的方法?
英文:
I would like to create a base struct which have to method, I want to use these methods in the substructs. For example:
type Base struct {
Type string `json:"$type"`
}
func (b Base) GetJSON() ([]byte, error) {
return json.Marshal(b)
}
func (b Base) SetType(typeStr string) interface{} {
b.Type = typeStr
return b
}
In the new struct I want to use it like this:
type Auth struct {
Base
Username
Password
}
and call these methods in the main:
func main() {
a := Auth{
Username: "Test",
Password: "test",
}
a = a.SetType("testtype").(Auth)
j, _ := a.GetJSON()
}
In the SetType case I got a panic caused by interface{} is not Auth
type, it is Base
type.
In the GetJSON case I got a json about the Type, but only the Type.
Is there any solution for the problem what I want to solve?
答案1
得分: 7
如评论中所提到的,嵌入不是继承,而是组合,所以你可能需要做以下两种选择之一:
- 重新思考你的设计,使用Go提供的工具
- 通过大量的修改来实现你想要的结果
在你展示的特定情况中(试图使GetJSON()
包含外部结构的字段),以下是一种可能的解决方法,它不需要太多的修改(只需在创建结构时将外部结构的指针存储在Base中):
package main
import (
"encoding/json"
"fmt"
)
type Base struct {
Type string `json:"$type"`
selfP interface{} // this will store a pointer to the actual sub struct
}
func (b *Base) SetSelfP(p interface{}) {
b.selfP = p
}
func (b *Base) GetJSON() ([]byte, error) {
return json.Marshal(b.selfP)
}
func (b *Base) SetType(typeStr string) {
b.Type = typeStr
}
type Auth struct {
Base
Username string
Password string
}
func main() {
a := &Auth{
Username: "Test",
Password: "test",
}
a.SetSelfP(a) // this line does the trick
a.SetType("testtype")
j, _ := a.GetJSON()
fmt.Println(string(j))
}
Playground链接:https://play.golang.org/p/npuy6XMk_t
英文:
As mentioned in the comments, embedding is not inheritance but composition, so you'll probably have to either:
- Re-think your design to use the tools Go has available
- Resort to extensive hacking to get the results you want
In the particular case you are showing (trying to get GetJSON()
to include also the fields of the outer struct, here is a possible way of getting that to work that does not require many changes (just storing a pointer to the outer struct in Base when creating the struct):
package main
import (
"encoding/json"
"fmt"
)
type Base struct {
Type string `json:"$type"`
selfP interface{} // this will store a pointer to the actual sub struct
}
func (b *Base) SetSelfP(p interface{}) {
b.selfP = p
}
func (b *Base) GetJSON() ([]byte, error) {
return json.Marshal(b.selfP)
}
func (b *Base) SetType(typeStr string) {
b.Type = typeStr
}
type Auth struct {
Base
Username string
Password string
}
func main() {
a := &Auth{
Username: "Test",
Password: "test",
}
a.SetSelfP(a) // this line does the trick
a.SetType("testtype")
j, _ := a.GetJSON()
fmt.Println(string(j))
}
Playground link: https://play.golang.org/p/npuy6XMk_t
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论