Golang基础结构用于定义子结构中的方法。

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

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

huangapple
  • 本文由 发表于 2017年8月11日 20:58:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/45635839.html
匿名

发表评论

匿名网友

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

确定