一、使用指针和结构体
1.结构体的定义
结构体是一系列具有指定数据类型的数据字段,通过使用结构体,可在单个变量中存储众多结构不同的数据字段。
package main
import "fmt"
type Movie struct {
Name string
Rating float32
}
func main() {
m := Movie{
Name: "Citizen Kane",
Rating: 10,
}
fmt.Println(m.Name, m.Rating)//输出Citizen Kane 10
}
- 关键字type指定一种新类型(就是C++的struct)
- 将新类型的名称指定为Movie
- 类型名右边是数据类型,这里为结构体
- 在大括号内,使用名称和类型指定了一系列的数据字段。请注意,此时没有给数据字段赋值。可将结构体视为模板。
- 在main函数中,使用简短变量赋值声明并初始化了变量m,给数据字段指定为相同的数据类型
- 使用点表示法访问数据字段并将其打印到控制台
2 创建结构体
由上面简单的例子我们可以看出,创建结构体的格式为type <结构体名> struct{<结构体定义>}
一个比较详细的使用例子如下:
package main
import "fmt"
type Movies struct {
Name string
Rating float32
}
func main() {
var m Movies
fmt.Printf("%+v\n", m)//{Name: Rating:0}
m.Name = "fadsfad"
m.Rating = 0.998
fmt.Printf("%+v\n", m)//输出{Name:fadsfad Rating:0.998}
}
在声明变量时,Movies并没有初始化,Movies的成员变量的值都是对应的零值
除了以上的定义结构体变量的方式外,还有如下几种:
- 使用关键词new来定义
m := new(Movies)
此时的m是一个指针类型的变量 - 使用简短变量赋值语句
c := Movies{Name:“dadf”,Rating:10} - 或者在2. 的基础上省略,成员变量名,但要注意对应关系
c := Movies(“dadf”,10) - 字段较多时,让每个字段独占一行可以有效提高代码的可维护性和可读性。
但要注意这样写的话,最后一行也必须以comma结尾c := Movies{ Name:"dadf", Rating:10, }
3 嵌套结构体
package main
import "fmt"
type Super struct {
Name string
Age int
address Address
}
type Address struct {
Number int
Street string
City string
}
func main() {
e := Super{
Name: "afdsa",
Age: 32,
address: Address{
Number: 1007,
Street: "adsf",
City: "fdafa",
},
}
fmt.Printf("%+v\n", e)
//输出{Name:afdsa Age:32 address:{Number:1007 Street:adsf City:fdafa}}
}
4 自定义结构体数据字段的默认值
- Go语言没有提供自定义默认值的内置方法,但可以使用构造函数来实现这个目标。
type Alarm struct{ Time string Sound string } func NewAlarm(time string)Alarm{ a:=Alarm{ Time:time, Sound:"adasf", } return a }
5 比较结构体
- 对结构体进行比较使用
==
和!=
来比较 - 只能同类型之间进行比较
- 可以使用
reflect
包检查结构体的类型
6 理解公有和私有值
- 这里的公有和私有的定义与C++略有差别。
- 如果一个值被导出,可在函数方法或包外面使用,那么他就是公有的
- 如果一个值只能在其所属上下文中使用,那么他就是私有的。
- 根据Go语言约定,结构体及其数据字段都可能被导出,也可能不导出。如果一个标识符的的首字母是大写的,那么它将被导出;否则不会导出
- 要导出结构体及其字段,结构体及其字段的名称都必须以大写字母开头。
7.区分指针引用和值引用
b:=a
,此时b和a有相同的值,不同的内存地址b:=&a
,此时b是指向a的指针,修改b时也将修改a
package main
import (
"fmt"
)
type Drink struct {
Name string
Ice bool
}
func main() {
a := Drink{
Name: "affadsf",
Ice: true,
}
b := &a
c := a
c.Ice = false
fmt.Printf("a:%+v\n", a)
fmt.Printf("b:%+v\n", *b)
fmt.Printf("c:%+v\n", c)
b.Ice = false
fmt.Printf("a:%+v\n", a)
fmt.Printf("b:%+v\n", *b)
fmt.Printf("c:%+v\n", c)
}
输出结果如下:
参考书籍
[1]: 【Go语言入门经典】[英] 乔治·奥尔波 著 张海燕 译
题外话
- 又是元气满满的一天。