Golang在c ++中代替父母返回子结构

时间:2017-03-03 07:01:24

标签: go

我正在尝试使用可以返回各种多个子对象的泛型函数。我们的想法是能够在json请求中返回那些。

代码如下

GenericType struct {
    V1 string `json:"v1"`
    V2 string `json:"v2"`
}

SubType struct {
    GenericType
    V3 string `json:"v3"`
}

func TestFunc() GenericType {
    val := SubType{
        GenericType: GenericType{
            V1: "a",
            V2: "b",
        },
        V3: "c",
    }
    return val
}

错误是

cannot use val (type SubType) as type GenericType in return argument

是否可以在父指针中返回后代结构而不丢失该后代结构的字段,然后将其作为响应主体中的JSON对象返回?

3 个答案:

答案 0 :(得分:1)

您不能使用嵌入作为继承的替代品。你可以使用接口。类似的东西:

type Generic interface {
    V1() string
    V2() string
}

type parent struct {
    // ...
}

type child struct {
    // ...
}

// parent
func (p *parent) V1() string {
    return "parent V1"
}

func (p *parent) V2() string {
    return "parent V2"
}

// child
func (c *child) V1() string {
    return "child V1"
}

func (c *child) V2() string {
    return "child V2"
}

// further child methods

func NewGeneric() Generic {
    return &parent{}
    // or 
    // return &child{}
}

答案 1 :(得分:0)

Go没有继承(如C ++或Java),但只有组合和接口。因此,您的函数只能返回一个类型结构(或指针)或接口。作为第一个近似,您可以认为接口与C ++中的纯抽象类几乎相同。

在您的情况下,界面更好。现在,这取决于程序的其余部分如何与返回值一起使用。如果它需要调用一些方法(在go中我们更喜欢仅使用少量方法的接口 - 理想的是一个)。

EG。

type GenericType interface {
    getV1() string
    getV2() string
}

但不幸的是 - 对于所有可以序列化为JSON的对象,我们没有任何常用方法(例如int,string或数组),因此我们必须使用没有通用方法的接口 - interface {}。

答案 2 :(得分:0)

嵌入

嵌入Go并不允许继承(因为它不是继承)属性。当你将一个结构嵌入到另一个结构中时,你正在编写它的结构。 方法(非属性)到新作品。

  

Go没有提供典型的,类型驱动的子类化概念,但它确实能够通过在结构或接口中嵌入类型来“借用”实现的各个部分。

接口

Go提供 awesome 接口来实现泛型类型和类型断言,以便能够访问具体类型及其'属性。

Plyground

type generic interface {
    say() string
}

type type1 struct {
    msg string
}

func (t type1) say() string {
    return t.msg
}

type type2 struct{}

func (t type2) say() string {
    return "I'm type 2"
}

func main() {
    t1 := type1{"Hey! I'm type1"}
    t2 := type2{}

    tl := []generic{t1, t2}

    for _, i := range tl {
        switch v := i.(type) {
        case type1:
            fmt.Println(v.say())
            fmt.Println(v.msg)
        case type2:
            fmt.Println(v.say())
            // fmt.Println(v.msg) Uncomment to see that type2 has no msg attribute.
        }
    }
}