#《Go 语音圣经(中文版)》

结构体可以作为函数的参数和返回值。

如果考虑效率的话,较大的结构体通常会用指针的方式传入和返回,

因为结构体通常通过指针处理,可以用下面的写法来创建并初始化一个结构体变量,并返回结构体的地址:

1
pp := &Point{1, 2}

如果结构体的全部成员都是可以比较的,那么结构体也是可以比较的。

Go语言有一个特性让我们只声明一个成员对应的数据类型而不指名成员的名字;这类成员就叫匿名成员
匿名成员的数据类型必须是命名的类型指向一个命名的类型的指针

全称访问的方式依然可以。

我们在访问子成员的时候可以忽略任何匿名成员部分。

结构体字面值并没有简短表示匿名成员的语法。

Printf函数中%v参数包含的#副词,它表示用和Go语言类似的语法打印值。

成员的名字是由其类型隐式地决定的,所以匿名成员也有可见性的规则约束。

在包外部,如果circlepoint没有导出,则不能访问它们的成员,因此简短的匿名成员访问语法也是禁止的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package main

/*
@Time : 2021/5/20 18:53
@Author : onns
@File : 4.8.go
*/

import "fmt"

type Point struct{ X, Y int }

func Scale(p Point, factor int) Point {
return Point{p.X * factor, p.Y * factor}
}

func Scale2(p *Point, factor int) {
p.X *= factor
p.Y *= factor
}

func main() {
p := Point{1, 2}
// pp = &p
fmt.Println(p)
// fmt.Println(&p)
p = Scale(p, 4)
fmt.Println(p)
Scale2(&p, 4)
fmt.Println(p)
// fmt.Println(&p)
}
1
2
3
4
[19:26:42] onns@Onns ~/Onns/code/go/go-bible/ch4 $ go run 4.8.go 
{1 2}
{4 8}
{16 32}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
package main

/*
@Time : 2021/5/20 19:35
@Author : onns
@File : 4.9.go
*/

import "fmt"

type Circle struct {
X, Y, Radius int
}

type Wheel struct {
X, Y, Radius, Spokes int
}

type Point struct {
X, Y int
}

type Circle2 struct {
Center Point
Radius int
}

type Wheel2 struct {
Circle Circle2
Spokes int
}

type Circle3 struct {
Point
Radius int
}

type Wheel3 struct {
Circle3
Spokes int
}

func main() {
var w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20
fmt.Println(w)

var w2 Wheel2
w2.Circle.Center.X = 8
w2.Circle.Center.Y = 8
w2.Circle.Radius = 5
w2.Spokes = 20
fmt.Println(w2)

var w3 Wheel3
// fmt.Println(w3)
w3.X = 8 // equivalent to w3.Circle3.Point.X = 8
w3.Y = 8 // equivalent to w3.Circle3.Point.Y = 8
w3.Radius = 5 // equivalent to w3.Circle3.Radius = 5
w3.Spokes = 20
fmt.Println(w3.Circle3.Point.X)
fmt.Println(w3)

w4 := Wheel3{Circle3{Point{8, 8}, 5}, 20}
fmt.Printf("%#v\n", w4)

w5 := Wheel3{
Circle3: Circle3{
Point: Point{X: 8, Y: 8},
Radius: 5,
},
Spokes: 20, // NOTE: trailing comma necessary here (and at Radius)
}
w5.X = 42
fmt.Printf("%#v\n", w5)
}
1
2
3
4
5
6
7
[19:30:42] onns@Onns ~/Onns/code/go/go-bible/ch4 $ go run 4.9.go 
{8 8 5 20}
{{{8 8} 5} 20}
8
{{{8 8} 5} 20}
main.Wheel3{Circle3:main.Circle3{Point:main.Point{X:8, Y:8}, Radius:5}, Spokes:20}
main.Wheel3{Circle3:main.Circle3{Point:main.Point{X:42, Y:8}, Radius:5}, Spokes:20}