嵌入式和领域的区别

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

Differences of embedded and field

问题

以下是翻译的内容:

这里有一个嵌入了结构体Struct1和一个作为字段定义的结构体Struct2。虽然fmt.Printf()的输出结果相同,但初始化方式有所不同。我对此感到困惑。非常抱歉。

  1. Struct1Struct2之间有什么区别?
  2. 在什么情况下应该使用它们?

代码

type sample1 struct {
    Data string
}

type sample2 struct {
    Data string
}

type Struct1 struct {
    *sample1
    *sample2
}

type Struct2 struct {
    Sample1 sample1
    Sample2 sample2
}

func main() {
    s1 := &Struct1{
        &sample1{},
        &sample2{},
    }
    s1.sample1.Data = "s1 sample1 data"
    s1.sample2.Data = "s1 sample2 data"

    s2 := &Struct2{}
    s2.Sample1.Data = "s2 sample1 data"
    s2.Sample2.Data = "s2 sample2 data"

    fmt.Printf("%s, %s\n", s1.sample1.Data, s1.sample2.Data)
    fmt.Printf("%s, %s\n", s2.Sample1.Data, s2.Sample2.Data)
}

https://play.golang.org/p/gUy6gwVJDP

非常感谢您的时间和建议。对于我的问题不成熟,我感到非常抱歉。

英文:

There are embedded struct Struct1 and a struct Struct2 defined as field. Both fmt.Printf() are same results while there is a difference for the initialization. I confused about this. I'm sorry.

  1. What differences are these between Struct1 and Struct2?
  2. Which should be used under what situation?

Script

type sample1 struct {
    Data string
}

type sample2 struct {
    Data string
}

type Struct1 struct {
    *sample1
    *sample2
}

type Struct2 struct {
    Sample1 sample1
    Sample2 sample2
}

func main() {
    s1 := &Struct1{
        &sample1{},
        &sample2{},
    }
    s1.sample1.Data = "s1 sample1 data"
    s1.sample2.Data = "s1 sample2 data"

    s2 := &Struct2{}
    s2.Sample1.Data = "s2 sample1 data"
    s2.Sample2.Data = "s2 sample2 data"

    fmt.Printf("%s, %s\n", s1.sample1.Data, s1.sample2.Data)
    fmt.Printf("%s, %s\n", s2.Sample1.Data, s2.Sample2.Data)
}

https://play.golang.org/p/gUy6gwVJDP

Thank you so much for your time and advices. And I'm sorry for my immature question.

答案1

得分: 1

关于第二个问题,个人而言,我主要使用嵌入来提升方法。

//定义接口
type Doer interface{
    Do()
}

//实现接口
func DoWith(d Doer){}

type sample1 struct{}
func (s sample1)Do(){}

type Struct1 struct {
    sample1
}

type Struct2 struct {
    Sample1 sample1
}

var s1 Struct1
var s2 Struct2

//可以调用
DoWith(s1) //方法被提升,所以满足接口要求

//但是无法调用
DoWith(s2)

关于解码JSON,

type Sample1 struct {
    Data string `json:"data"`
}

type Sample2 struct {
    Number int `json:"number"`
}

type Struct1 struct {
    Sample1
    Sample2
}

var s1 Struct1
json.Unmarshal([]byte(`{"data": "foo", "number": 5}`), &s1)
fmt.Println(s1.Data, s1.Number) //输出 foo 5
英文:

As about second question, personally I mostly use embedding to promote methods

//having
type Doer interface{
    Do()
}
func DoWith(d Doer){}
func (s sample1)Do(){} //implemented
type Struct1 struct {
    sample1
}
type Struct2 struct {
    Sample1 sample1
}
var s1 Struct1
var s2 Struct2
//you can call
DoWith(s1) //method promoted so interface satisfied
//but cannot
DoWith(s2)

and to decode JSON,

//having
type Sample1 struct {
    Data string `json:"data"`
}
type Sample2 struct {
    Number int `json:"number"`
}
//you can easy and handy compose
type Struct1 struct {
	Sample1
    Sample2
}
var s1 Struct1
json.Unmarshal([]byte(`{"data": "foo", "number": 5}`), &s1)
fmt.Println(s1.Data, s1.Number) //print foo 5

huangapple
  • 本文由 发表于 2017年5月14日 15:09:08
  • 转载请务必保留本文链接:https://go.coder-hub.com/43961290.html
匿名

发表评论

匿名网友

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

确定