2018-05-02 Anonymous fields in Go

摘要:Go中的Anonymous fields使得我们可以缩写点语法,同时也允许我们使用compositions来给一个方法添加类型
转自: Anonymous fields in Go

Anonymous fields in Go structures allow us to shortcut dot notation as well as allow us to use compositions to add methods to a type.

Shortcutting the dot notation
For example if we have something like this

type A struct {
    X int
    Y int
}

type B struct {
    Z int
}

type C struct {
    AValue A
    BValue B
}

then to access the field X on AValue we’d write code like this

c := C {}
c.AValue.X = 1

Changing the C struct fields to anonymous (i.e. removing the field name) like this

type C struct {
    A
    B
}

allows us to reduce the use of the dot notation and access X on A as if it was a field within the C struct itself, i.e.

c := C {}
c.X = 1

Okay, but what if B struct now replaced the Z field name with X, i.e.

type A struct {
    X int
    Y int
}

type B struct {
    X int
}

We now have a situation where both A and B have the same field name, well we can still use anonymous fields, but we’re back to using more dot notation again to get around the obvious field name conflict, i.e.

c := C {}
c.A.X = 1
c.B.X = 2

Initializers do not support shortcutting
Unfortunately we not get the advantage of the anonymous fields with the initializer syntax, i.e. We must specify the A and B structs like this

c := C{ A : A{2, 4}, B : B { 12 }}

// or

c := C{ A : A{X : 2, Y : 4}, B : B { Z: 12 }}

// but this doesn't compile
c := C{ X : 2, Y : 4, Z : 12 }
// nor does this compile
c := C{ A.X : 2, A.Y = 3, B.Z : 12 }

Composition
More powerful than the synaptic sugar of embedded/anonymous fields, we can also use composition to increase the methods available on the struct C. For example let’s now add a method to the A type which allows us to move our X, Y point

func (a *A) Move(amount int) {
    a.X += amount
    a.Y += amount
}

Now we can call the method on the previously declared c
variable like this

c.Move(10)

We can also create further methods via a composition pattern on type C if we want using empty types, let’s assume we have type D and extend the composition of type C

type D struct {}

type C struct {
    A
    B
    D
}

now we can add methods to D and ofcourse they’ll be available as part of C. So for example, maybe D acts as a receiver for methods that serialize data to JSON, now our C type will also appear to have those methods.

你可能感兴趣的:(2018-05-02 Anonymous fields in Go)