Go语言的关键字type可以将各种基本类型定义为自定义类型,基本类型包括整型、字符串、布尔等。结构体是一种复合的基本类型,通过type定义为自定义类型后,使结构体更便于使用。
1.结构体定义格式
type 类型名 struct {
字段1 字段1类型
字段2 字段2类型
......
}
类型名:标识自定义结构体的名称,在同一个包内不能重复
struct{}:标识结构体类型,等价于C语言中的:
typedef struct {
字段1类型 字段1,
字段2类型 字段2,
......
}类型名;
注意:结构体的定义只是一种内存布局的描述,只有当结构体实例化时,才会真正地分配内存。
2.结构体实例化
(1)基本实例化形式
//先声明结构体变量再赋值
type Point struct {
X int
Y int
}
var p Point
p.X = 10
p.Y = 20
或者
var p Point = Point{
X:19,
Y:23,
}
(2)声明的同时进行初始化
type Point struct {
X int
Y int
}
var p = Point{
X:10,
Y:10,
}
(3)创建指针类型结构体
Go语言中,和C++一样可以使用new来创建指定类型的指针变量。但是和C++不同的是,C++中使用new实例化类型以后,访问其成员变量时必须使用->操作符,而在Go语言中,都使用“.”进行访问。
ins := new(T)
T:类型,可以是结构体、整型、字符串等
ins:T类型被实例化后保存到ins变量中,ins的类型为*T,属于指针
(4)取结构体的地址实例化
Go语言中,对结构体进行&取地址操作时,视为对该类型进行一次new的实例化操作。
ins := &T{}
T:表示结构体类型
ins:结构体实例,类型为*T,是指针类型
type Command struct {
Name string
Comment string
}
cmd := &Command struct {
Name:"version1.0",
Comment:"version info",
}
cmd1 := &Command{}
cmd1.Name = "version2.0"
cmd1.Comment = "version info"
3.结构体成员变量初始化
结构体在实例化时可以直接对成员变量进行初始化。初始化有两种形式,一种是“键值对”形式,另一种是多个值的列表形式。键值对形式的初始化适合选择性填充字段较多的结构体;多个值的列表形式适合填充字段比较少的结构体。
(1)使用“键值对”初始化结构体
举例说明:
type Person struct {
Name string
Age int
Sex string
}
p := Person{
Name: "zk",
Age : 12,
Sex : "man",
}
注意:键值对的填充是可选的,不需要初始化的字段可以不填入初始化列表中。
(2)值列表初始化结构体
举例说明:
type Person struct {
Name string
Sex sting
Age int
}
p := Person {
"zk",
"man",
12,
}
注意:使用多个值的列表初始化结构体时必须初始化结构体的所有字段,且每个初始值的填充顺序必须和字段在结构体中声明顺序一致。这个和C/C++一致。
注意:结构体成员中只能包含结构体的指针类型,包含非指针类型会引起编译错误。
(3)初始化匿名结构体
匿名结构体没有类型名称,无须通过type关键字定义就可以直接使用。
//方式1
ins := struct {
id int
data string
}{
id : 1001,
data : "hello",
}
//方式2
ins := struct {
id int
data string
}{}
ins.id = 12
ins.data = "zk"
4.结构体内嵌
结构体允许其成员字段在声明时没有字段名而只有类型,这种形式的字段被称为类型内嵌或匿名字段类型内嵌。
(1)写法
type Data struct {
int
float32
bool
}
ins := &Data{
int: 10,
float32: 3.14,
bool: true,
}
注意:类型内嵌其实拥有自己的字段名,只是字段名就是其类型本身而已,结构体要求字段名必须唯一,因此一个结构体中同类型的匿名字段只能有一个。
结构体实例化以后,如果匿名的字段类型为结构体,那么可以直接访问匿名结构体内的所有成员,这种方式被称为结构体内嵌。
(2)结构体内嵌特性
内嵌的结构体可以直接访问其成员变量
内嵌结构体的字段名是它的类型名
(3)初始化内嵌结构体
//举例说明
package main
import "fmt"
type Wheel struct {
Size int
}
type Engine struct {
Power int
Type string
}
type Car struct {
Wheel
Engine
}
func main() {
c := Car{
Wheel:Wheel{
Size:18,
},
Engine:Engine{
Power:18,
Type:"1.4T",
},
}
}