Go 语言笔记:结构体
结构体
结构体是一种将一个或者多个任意类型的值聚合的实体,每个值称为结构体的成员,其实结构体就是 Go
语言中的类。
结构体的声明
结构体可以使用以下格式进行声明
go
type struct_name struct {
attribute_name attribute_type
...
}
例如我们定一个数据源实体 DataSource
go
type DataSource struct {
url string
user_name string
password string
driver_class_name string
}
成员的类型如果一致,可以定义在同一行,以逗号隔开
go
type DataSource struct {
url, user_name, password, driver_class_name string
}
声明结构体也可以不使用 type
关键字,例如我们使用 var
关键字声明一个匿名的结构体
go
var DataSource struct {
url string
username string
password string
}
结构体的创建
我们可以使用结构体成员名称来创建结构体,例如我们创建一个名为 Movie
的结构体,包含名称和上映年份成员。
go
type Movie struct {
name string
year int
}
使用成员名来初始化结构体
go
mov := Movie {
name: "肖申克的救赎",
year: 1994
}
不使用成员初始化结构体
go
mov := Movie {"肖申克的救赎", 1994}
初始化匿名结构体
go
mov := struct {
name string,
year int
} {
name: "肖申克的救赎",
year: 1994
}
结构体中的成员变量如果没有显示的赋值,那么它的值是初始化的零值,string
类型的零值为空字符串 ""
,int
类型的零值为 0。
结构体的使用
我们可以使用操作符 .
来给结构体的成员赋值,或者对其访问。
go
type Movie struct {
name string
year int
}
var mov = Movie {}
mov.name = "肖申克的救赎"
mov.year = 1994
fmt.Println(mov.name) // 肖申克的救赎
fmt.Println(mov.year) // 1994
除了以上使用创建出来的实体来访问其成员以外,我们也可以使用指针来访问
go
mov := &Movie {"肖申克的救赎", 1994}
fmt.Println((*mov).name) // 肖申克的救赎
fmt.Println(mov.name) // 肖申克的救赎
对于字段也匿名的结构体如何访问呢,且看下面的例子
go
type Movie struct {
string
int
}
mov := Movie{"肖申克的救赎", 1994}
fmt.Println(mov.string) // 肖申克的救赎
匿名字段只支持该类型在结构体中只有一个的情况才可以使用以上方式进行访问。
嵌套结构体
结构体的成员也可以是一个结构体,这样的结构体就是嵌套结构体
go
type Date struct {
year, month, day int
}
type Movie struct {
name string
date Date
}
mov := Movie {
name: "肖申克的救赎",
date: Date {1994, 12, 12}
}
fmt.Println(mov.date.year) // 1994
结构体字段提升
结构体中如果有匿名的结构体类型,那么匿名的结构体中的字段则成为 提升字段
, 提升字段的好处就是,可以直接使用外部结构体来访问,而不用像上面的必须通过中间的名称 mov.date.year
来访问。
go
type Date struct {
year, month, day int
}
type Movie struct {
name string
Date
}
movies := Movie{name:"肖申克的救赎", Date: Date{1994, 12, 12}}
fmt.Println(movies.year) // 1994, 直接访问提升字段
结构体的方法
Go
语言结构体中无法直接定义方法,但是我们可以将方法绑定给某个结构体。
go
package main
import "fmt"
type Movie struct {
name string
year int
}
func (movie Movie) Display() {
fmt.Println(movie.name)
fmt.Println(movie.year)
}
func main() {
mov := Movie{"肖申克的救赎", 1994}
mov.Display()
}
// 打印结果:
肖申克的救赎
1994
结构体属性通过方法修改
结构体的属性需要通过方法来修改时,必须传递结构体的指针。
go
package main
import "fmt"
type Movie struct {
name string
year int
}
// 传递mov的副本,只能读取其属性的值,不能修改mov
func (movie Movie) display() {
fmt.Println(movie.name)
fmt.Println(movie.year)
}
// 传递指针,可以通过指针修改其属性的值
func (movie *Movie) Correct(year int) {
movie.year = movie.year + year
}
func main() {
mov := Movie{"肖申克的救赎", 1994}
mov.Correct(1)
fmt.Println(mov.year) // 1995
}
结构体方法的访问权限
在 Go
语言中,方法通过名称首字母的大小写来区分内部方法还是外部方法。
- 当方法名称的首字母为大写时,该方法对于所有包都是
Public
,其他包可以任意访问 - 当方法名称的首字母为小写时,该方法是
Private
,其他包是无法访问的