Golang, c ++ kabi ota-onaning o'rniga bola tuzilishini qaytaradi

Turli xil ko'plab bolalar ob'ektlarini qaytarib beradigan umumiy funktsiyaga ega bo'lishga harakat qilaman. Ushbu g'oya json tanasining talabiga binoan ularni qaytarib olishdir.

Kod quyidagicha

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
}

Xato

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

Ota-ona imo-ishoralardagi darvoza strukturasini bu avlodning tuzilmalari maydonlarini yo'qotmasdan qaytarib berishi va keyin uni JSON obyekti sifatida javob organiga qaytarish mumkinmi?

0
@Havelock, bu haqiqat emas, balki Go var Polimorfizm C ++ da polimorfizmdan farq qiladi stackoverflow.com/a/41592747/629685
qo'shib qo'ydi muallif I159, manba
Go OOP tili emas ekan, polimorfizm yo'q. Qanday foydalansangiz, interfeys
qo'shib qo'ydi muallif Havelock, manba

6 javoblar

Ichki o'rnatishni merosni almashtirish sifatida foydalana olmaysiz. Buning uchun interfeyslarni ishlatishingiz mumkin. Bir narsa:

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
qo'shib qo'ydi

Ichki o'rnatishni merosni almashtirish sifatida foydalana olmaysiz. Buning uchun interfeyslarni ishlatishingiz mumkin. Bir narsa:

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
qo'shib qo'ydi

Ko'rinish

Ko'rinish in Go doesn't allow to inherit (since it is not inheritance) attributes. When you are Ko'rinish one struct to another you are composing its' methods (not attributes) to a new composition.

Go does not provide the typical, type-driven notion of subclassing, but it does have the ability to “borrow” pieces of an implementation by Ko'rinish types within a struct or interface.

Interfeyslar

Go provides awesome Interfeyslar to implement generic types and type assertion to have access to concrete types and its' attributes.

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.
        }
    }
}
0
qo'shib qo'ydi

Ko'rinish

Ko'rinish in Go doesn't allow to inherit (since it is not inheritance) attributes. When you are Ko'rinish one struct to another you are composing its' methods (not attributes) to a new composition.

Go does not provide the typical, type-driven notion of subclassing, but it does have the ability to “borrow” pieces of an implementation by Ko'rinish types within a struct or interface.

Interfeyslar

Go provides awesome Interfeyslar to implement generic types and type assertion to have access to concrete types and its' attributes.

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.
        }
    }
}
0
qo'shib qo'ydi

Goning miriqasi yo'q (C ++ yoki Java kabi), faqat kompozitsiya va interfeys. Shuning uchun funktsiyangiz faqat bitta turdagi strukturani (yoki markerni) yoki interfeysni qaytarishi mumkin. Birinchi taxminan siz interfeysi C ++ da sof mavhum sinf bilan deyarli bir xil deb o'ylashingiz mumkin.

Sizning vaziyatingizda interfeys yaxshi. Va endi dasturning qolgan qismi qaytib qiymat bilan ishlashga bog'liq. Agar bir necha usulni izlash kerak bo'lsa (faqatgina bir nechta usuli bilan interfeysni afzal ko'rsak - ideal).

Misol uchun.

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

But unfortunately - for all object that could be serialized into JSON we don't have any common method (Misol uchun.int, string or arrays), therefore we have to use interface with no common method - interface{}.

0
qo'shib qo'ydi

Goning miriqasi yo'q (C ++ yoki Java kabi), faqat kompozitsiya va interfeys. Shuning uchun funktsiyangiz faqat bitta turdagi strukturani (yoki markerni) yoki interfeysni qaytarishi mumkin. Birinchi taxminan siz interfeysi C ++ da sof mavhum sinf bilan deyarli bir xil deb o'ylashingiz mumkin.

Sizning vaziyatingizda interfeys yaxshi. Va endi dasturning qolgan qismi qaytib qiymat bilan ishlashga bog'liq. Agar bir necha usulni izlash kerak bo'lsa (faqatgina bir nechta usuli bilan interfeysni afzal ko'rsak - ideal).

Misol uchun.

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

But unfortunately - for all object that could be serialized into JSON we don't have any common method (Misol uchun.int, string or arrays), therefore we have to use interface with no common method - interface{}.

0
qo'shib qo'ydi