本文摘自php中文网,作者尚,侵删。

定义:是一种聚合的数据类型,是由零个或多个任意类型的值聚合成的实体。
成员:每个值称为结构体的成员。
示例:
用结构体的经典案例处理公司的员工信息,每个员工信息包含一个唯一的员工编号、员工的名字、家庭住址、出生日期、工作岗位、薪资、上级领导等等。所有的这些信息都需要绑定到一个实体中,可以作为一个整体单元被复制,作为函数的参数或返回值,或者是被存储到数组中,等等。
定义结构体:
1 2 3 4 5 6 7 8 9 | type Employee struct {
ID int
Name string
Address string
DoB time.Time
Position string
Salary int
ManagerID int
}
|
定义变量:
访问成员:
取成员地址:
1 2 | position := &dilbert.Position
*position = "Senior " + *position
|
点操作符与指向结构体的指针:
1 2 | var employeeOfTheMonth *Employee = &dilbert
employeeOfTheMonth.Position += " (proactive team player)"
|
成员定义顺序:
通常一行对应一个结构体成员,成员的名字在前类型在后,不过如果相邻的成员类型如果相同的话可以被合并到一行,就像下面的Name和Address成员那样
1 2 3 4 5 6 7 8 | type Employee struct {
ID int
Name, Address string
DoB time.Time
Position string
Salary int
ManagerID int
}
|
成员命名规则:
如果结构体成员名字是以大写字母开头的,那么该成员就是导出的;这是Go语言导出规则决定的。一个结构体可能同时包含导出和未导出的成员。
导出含义:在其他包中可进行读写。
一个命名为S的结构体类型将不能再包含S类型的成员:因为一个聚合的值不能包含它自身。(该限制同样适应于数组。)但是S类型的结构体可以包含*S指针类型的成员,这可以让我们创建递归的数据结构,比如链表和树结构等。
1 2 3 4 | type tree struct {
value int
left, right *tree
}
|
结构体面值:
可以指定每个成员的值。
1 2 | type Point struct{ X, Y int }
p := Point{1, 2}
|
上面的是第一种写法,要求以结构体成员定义的顺序为每个结构体成员指定一个面值。还可以:
1 | anim := gif.GIF{LoopCount: nframes}
|
以成员名字和相应的值来初始化,可以包含部分或全部的成员;在这种形式的结构体面值写法中,如果成员被忽略的话将默认用零值。因为,提供了成员的名字,所有成员出现的顺序并不重要。
注意:两种不同形式的写法不能混合使用。
结构体嵌入和匿名成员:
1 2 3 4 5 6 7 8 9 10 11 12 13 | type Point struct {
X, Y int
}
type Circle struct {
Center Point
Radius int
}
type Wheel struct {
Circle Circle
Spokes int
}
|
访问每个成员:
1 2 3 4 5 | var w Wheel
w.Circle.Center.X = 8
w.Circle.Center.Y = 8
w.Circle.Radius = 5
w.Spokes = 20
|
在次简化结构体定义:
1 2 3 4 5 6 7 8 9 | type Circle struct {
Point
Radius int
}
type Wheel struct {
Circle
Spokes int
}
|
得意于匿名嵌入的特性,我们可以直接访问叶子属性而不需要给出完整的路径:
1 2 3 4 5 | var w Wheel
w.X = 8
w.Y = 8
w.Radius = 5
w.Spokes = 20
|
结构体字面值必须遵循形状类型声明时的结构,所以只能用下面的两种语法,它们彼此是等价的:
1 2 3 4 5 6 7 8 9 | w = Wheel{Circle{Point{8, 8}, 5}, 20}
w = Wheel{
Circle: Circle{
Point: Point{X: 8, Y: 8},
Radius: 5,
},
Spokes: 20,
}
|
结构体tag:
在结构体声明中,Year和Color成员后面的字符串面值是结构体成员Tag
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | type Movie struct {
Title string
Year int `json: "released" `
Color bool `json: "color,omitempty" `
Actors []string
}
var movies = []Movie{
{Title: "Casablanca" , Year: 1942, Color: false ,
Actors: []string{ "Humphrey Bogart" , "Ingrid Bergman" }},
{Title: "Cool Hand Luke" , Year: 1967, Color: true ,
Actors: []string{ "Paul Newman" }},
{Title: "Bullitt" , Year: 1968, Color: true ,
Actors: []string{ "Steve McQueen" , "Jacqueline Bisset" }},
}
|
这样的数据结构特别适合JSON格式,并且在两种之间相互转换也很容易。将一个Go语言中类似movies的结构体slice转为JSON的过程叫编组(marshaling)。编组通过调用json.Marshal函数完成:
1 2 3 4 5 | data, err := json.Marshal(movies)
if err != nil {
log.Fatalf( "JSON marshaling failed: %s" , err)
}
fmt.Printf( "%s\n" , data)
|
Marshal函数返还一个编码后的字节slice,包含很长的字符串,并且没有空白缩进;我们将它折行以便于显示:
1 2 3 4 | [{ "Title" : "Casablanca" , "released" :1942, "Actors" :[ "Humphrey Bogart" , "Ingr
id Bergman" ]},{ "Title" : "Cool Hand Luke" , "released" :1967, "color" : true , "Ac
tors" :[ "Paul Newman" ]},{ "Title" : "Bullitt" , "released" :1968, "color" : true , "
Actors" :[ "Steve McQueen" , "Jacqueline Bisset" ]}]
|
其中Year名字的成员在编码后变成了released,还有Color成员编码后变成了小写字母开头的color。这是因为构体成员Tag所导致的。一个构体成员Tag是和在编译阶段关联到该成员的元信息字符串:
1 2 | Year int `json: "released" `
Color bool `json: "color,omitempty" `
|
结构体的成员Tag可以是任意的字符串面值,但是通常是一系列用空格分隔的key:"value"键值对序列;因为值中含义双引号字符,因此成员Tag一般用原生字符串面值的形式书写。
更多go语言知识请关注go语言教程栏目。
以上就是go语言结构体详解的详细内容,更多文章请关注木庄网络博客!!
相关阅读 >>
yum怎么安装Go语言
Go语言有指针吗
Go语言常用命令有哪些
Go语言支持安卓开发吗
Go语言math包中有哪些常用方法
Go语言和java语言的区别是什么?
Go语言如何获取时间戳
Go语言查看环境信息的方法
Go语言和python有什么区别?
Go语言跨平台吗
更多相关阅读请进入《Go语言》频道 >>
老貘
一个与时俱进的Go编程知识库。
转载请注明出处:木庄网络博客 » go语言结构体详解