前言
前面的两篇文章对 Go 语言的基础语法和基本数据类型以及几个复合数据类型进行介绍,本文将对 Go 里面的指针和结构体进行介绍,也为后续文章做铺垫。
指针
GoGointfloat64string*int*float64*string
指针的定义
var 指针变量名 *数据类型 = &变量
&&
import ( "fmt" ) func main() { var num int = 666 var numPtr *int = &num fmt.Println(numPtr) // num 变量的地址值 0xc00001c098 fmt.Println(&numPtr) // 指针变量本身的地址值 0xc00000a028 }
npmPtrnum0xc00001c098num0xc00000a028
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 }
PersonPhonePhoneBrandOwnerOwnerPerson
结构体的创建方式
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 语言并不推荐我们用这种方式进行赋值,因为可能会带来一些问题,例如结构体的某个中间的字段被删除或者字段的顺序改变了,那么我们需要维护对应代码,调整赋值的顺序。
上述创建结构体的方式有弊端,因此我们需要换一种方法,如下第三种方法。
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} }
通过以上的方式,我们就不被字段的顺序所约束了。
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
小结
本文对指针和结构体进行了介绍,也指出使用指针和结构体时需要注意的一些地方。因为本文是基于了解的层面去写的文章,一些深入的知识并没有提到,然后也没有提到结构体的方法,是因为打算留到后面和函数一起去介绍。