【问题标题】:Golang base struct to define methods in substructsGolang 基础结构在子结构中定义方法
【发布时间】:2017-08-11 21:27:48
【问题描述】:

我想创建一个必须方法的基本结构,我想在子结构中使用这些方法。例如:

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
  Password
}

并在main中调用这些方法:

func main() {
  a := Auth{
    Username: "Test",
    Password: "test",
  }
  a = a.SetType("testtype").(Auth) 
  j, _ := a.GetJSON()
}

在 SetType 的情况下,我得到一个由 interface{} 引起的恐慌不是Auth 类型,而是Base 类型。 在 GetJSON 案例中,我得到了一个关于类型的 json,但只有类型。

我想解决的问题有什么解决办法吗?

【问题讨论】:

  • return b.Type = typeStr 不是有效的 Go 语句。如果您正在尝试这样做,则 Base 不会有 UsernamePassword 字段。 Go 中没有继承。
  • 我建议您完全从 Go 的角度重新思考您的设计。 Go 不是面向对象的语言。它没有继承,也没有接口之外的多态性。
  • 是的,我知道,但是人们如何解决给定的问题,我有 359 个结构都使用相同的方法,我应该把它们写给所有人吗?
  • @JimB 我修好了
  • @PumpkinSeed:为什么它需要基于方法?大多数时候,人们会创建采用已定义接口的函数。大量重复代码的另一种解决方案当然是代码生成。

标签: go struct static-typing


【解决方案1】:

正如 cmets 中所述,嵌入不是继承而是组合,因此您可能必须:

  • 重新思考您的设计以使用 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))
}

游乐场链接:https://play.golang.org/p/npuy6XMk_t

【讨论】:

  • 谢谢,这正是我要找的。​​span>
  • 这个解决方案会被认为是 hacky 吗?它确实可以解决问题,并且有助于代码重复,是否应该避免这种解决方案?
  • @DusanGligoric 我更喜欢将这些方法制作成包函数以避免重复。
猜你喜欢
  • 2016-04-05
  • 2013-10-20
  • 2022-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-07-30
  • 2014-11-24
  • 1970-01-01
相关资源
最近更新 更多