开启生长之旅!这是我参加「日新方案 12 月更文挑战」的第5天,点击查看活动详情
耐性和持久胜过剧烈和疯狂。
前语
前面的两篇文章对 Go 语言的基础语法和根本数据类型以及几个复合数据类型进行介绍,本文将对 Go 里边的指针和结构体进行介绍,也为后续文章做衬托。
指针
在 Go
语言中,指针能够简略了解是一个地址,指针类型是依托于某一个类型而存在的,例如 Go
里边的根本数据类型 int
、float64
、string
等,它们所对应的指针类型为 *int
、*float64
、*string
等。
指针的界说
-
&
为取地址符号,经过&
符号获取某个变量的地址,然后赋值给指针变量。import ( "fmt" ) func main() { var num int = 666 var numPtr *int = &num fmt.Println(numPtr) // num 变量的地址值 0xc00001c098 fmt.Println(&numPtr) // 指针变量自身的地址值 0xc00000a028 }
npmPtr
指针变量指向变量num
,0xc00001c098
为num
变量的地址,0xc00000a028
为指针变量自身的地址值。 -
运用
new(T)
函数创立指针变量import ( "fmt" ) func main() { numPtr := new(int) fmt.Println(numPtr) // 0xc000122058 fmt.Println(*numPtr) // 0 }
new(T)
函数为每个类型分配一片内存,内存单元保存的是对应类型的零值,函数回来一个指针类型。 -
过错的类型地址赋值
func main() { var num float64 = 666 var numPtr *int = &num // cannot use &num (value of type *float64) as type *int in variable declaration }
当指针所依托的类型与变量的类型不一致时,Go 编译器会报错,类型不匹配。
获取和修正指针所指向变量的值
- 经过指针获取所指向变量的值
对指针运用func main() { var num int = 666 var numPtr *int = &num // 获取 num 的值 fmt.Println(*numPtr) // 666 }
*
操作符能够获取所指向变量的值。 - 经过指针修正所指向变量的值
同时也能够对指针运用import ( "fmt" ) func main() { var num int = 666 var numPtr *int = &num // 修正 num 的值 *numPtr = 555 fmt.Println(num) // 555 }
*
操作符修正所指向变量的值。
结构体
经过上一篇文章,咱们了解了数组和切片的特点,它们能够存储一组相同类型的数据,而结构体,它能够由 0 个或多个字段组成,每个字段的数据类型能够相同,也能够不相同。结构体能够表明一个目标,例如:人,人包括的一些字段有名字、性别和年纪等。
结构体界说
语法格局:
type XXX struct {
/*
结构体字段界说区域
*/
}
XXX
为结构体的名字,下面以人为目标,引入结构体
// Person界说一个人的结构体
type Person struct {
// 名字
Name string
// 年纪
Age int
// 性别
Sex string
// 身份证号
idNumber string
}
上述代码界说了人的结构体 Person
,包括四个字段,字段的命名规矩和变量是相同的,前三个字段首字母大写,能够被包外拜访,第四个字段首字母小写,表明只能在包内拜访。
除了上述的界说方法以外,结构体里还能够内嵌结构体
// Person 界说一个人的结构体
type Person struct {
// 名字
Name string
// 年纪
Age int
// 性别
Sex string
// 身份证号
idNumber string
}
// Phone 手机结构体
type Phone struct {
// 品牌
Brand string
// 具有者
Owner Person
}
上述代码界说了 Person
结构体和 Phone
结构体,Phone
结构体具有两个字段,分别为 Brand
品牌和 Owner
具有者,Owner
特点的类型,指定为咱们所自界说的 Person
结构体。以这种方法界说的结构体字段,咱们能够称为嵌入字段(Embedded Field)。也能够将这种字段称为匿名字段。
结构体的创立方法
- 1、声明一个结构体变量
// Person 界说一个人的结构体 type Person struct { // 名字 Name string // 年纪 Age int // 性别 Sex string // 身份证号 idNumber string } func main() { var person Person fmt.Println(person.Name) // "" fmt.Println(person.Age) // 0 fmt.Println(person.Sex) // "" fmt.Println(person.idNumber) // "" // 修正结构体字段的值 person.Name = "chenmingyong" fmt.Println(person.Name) // "chenmingyong" }
- 经过声明一个结构体变量,隐式创立一个结构体变量,这个结构体变量各个字段值默认为零值,也就是对应类型的默认值。
- 结构体特点的值,能够经过
变量.字段名
的方法获取,同时也能够经过此方法对字段值进行修正。
- 2、运用复合字面值进行显式初始化结构体目标
import "fmt" // Person 界说一个人的结构体 type Person struct { // 名字 Name string // 年纪 Age int // 性别 Sex string // 身份证号 idNumber string } func main() { person := Person{ "chenmingyong", 18, "男", "xxxxxxxxx", } fmt.Println(person) // {chenmingyong 18 男 xxxxxxxxx} }
- 上述代码依据字段的次序进行赋值,实际上,Go 语言并不引荐咱们用这种方法进行赋值,由于可能会带来一些问题,例如结构体的某个中心的字段被删去或者字段的次序改变了,那么咱们需求维护对应代码,调整赋值的次序。
- 上述创立结构体的方法有弊端,因而咱们需求换一种方法,如下第三种方法。
- 3、 运用
field:value
形式的复合字面值进行显式初始化结构体目标
经过以上的方法,咱们就不被字段的次序所约束了。import "fmt" // Person 界说一个人的结构体 type Person struct { // 名字 Name string // 年纪 Age int // 性别 Sex string // 身份证号 idNumber string } func main() { person := Person{ Sex: "男", Age: 18, Name: "chenmingyong", idNumber: "xxxxxxxxx", } fmt.Println(person) // {chenmingyong 18 男 xxxxxxxxx} }
- 4、经过
new(T)
函数创立结构体指针
前面说到过,拜访指针所指向变量的值,需求运用// Person 界说一个人的结构体 type Person struct { // 名字 Name string // 年纪 Age int // 性别 Sex string // 身份证号 idNumber string } func main() { person := new(Person) (*person).Name = "chenmignyong" fmt.Println((*person).Name) // chenmignyong // 简化赋值,底层主动转换成 (*person).Age = 18 person.Age = 18 fmt.Println(person.Age) // 18 }
*
操作符,但在结构体这儿有点特殊,假如不加*
的话,底层会将person.Age = 18
转成(*person).Age = 18
。
小结
本文对指针和结构体进行了介绍,也指出运用指针和结构体时需求注意的一些当地。由于本文是基于了解的层面去写的文章,一些深入的常识并没有说到,然后也没有说到结构体的方法,是由于打算留到后边和函数一起去介绍。
假如本文对你有帮助,欢迎点赞收藏加重视,假如本文有过错的当地,欢迎指出!