一、概述:
结构体是一种聚合的数据类型,它是由一系列相同或不同类型的数据字段构成的数据集合,每个数据字段称为结构体的成员或者属性;
go 语言中的struct 和C语言的struct 基本一样;与在java 中通过class 关键字定义的一个类也类似;只是go 语言中摒弃了class 关键字, 而且也没有继承、多态。
二、示例:
定义结构体
type Books struct {
bookId int
bookTitle string
bookAuthor string
bookSubject string
}
结构体普通变量初始化
- 顺序初始化
- 指定初始化
func initBook() {
//顺序初始化, 必须初始化所有成员
bookOne := Books{
1,
"C 语言",
"谭浩强",
"C 语言入门教程",
}
fmt.Printf("bookOne's info is %v \n", bookOne)
//指定初始化,没有初始化的成员,自动赋值为0
bookTwo := Books{
bookId: 2,
bookTitle: "go 语言编程",
bookAuthor: "许世伟",
}
fmt.Printf("bookTwo's info is %v \n", bookTwo)
}
结构体指针变量初始化
//结构体指针变量初始化
func initBookByPointer() {
var p1 *Books = &Books{
3,
"Think in java ",
"布鲁斯·埃克尔",
"java 语言经典教程",
}
fmt.Printf("book 00003's info is %v \n", *p1)
p2 := &Books{
bookId: 4,
bookTitle: "Python for Data Analysis",
bookAuthor: "韦斯·麦金尼",
bookSubject: "python 数据分析",
}
//go 语言中 引用指针变量, 也可以不用 *
fmt.Printf("book 00004's info is %v \n", p2)
//查看p2 的类型
fmt.Printf("p2 type is %T \n", p2) //*main.Books
}
结构体变量操作
func operateVariable() {
//普通变量
var b Books
//通过 '.' 来访问成员
b.bookId = 5
b.bookTitle = "活着"
b.bookAuthor = "余华"
b.bookSubject = "活着-没有比活着更好的事,也没有比活着更艰难的事"
fmt.Printf("b = %v \n", b)
//定义一个普通变量bb
var bb Books
//定义一个指针变量pp
var pp *Books
pp = &bb
//通过指针操作成员, pp.bookSubject 和 (*pp).bookSubject 是完全等价的
bb.bookId = 6
pp.bookTitle = "许三观卖血记"
bb.bookAuthor = "余华"
(*pp).bookSubject = "许三观卖血-人在面对厄运时求生的欲望"
fmt.Printf("bb = %v, pp = %v \n", bb, pp)
//通过new 申请一个结构体变量
p := new(Books)
p.bookId = 7
p.bookTitle = "老人与海"
p.bookAuthor = "海明威"
p.bookSubject = "现在不是去想缺少什么的时候,该想一想凭现有的东西你能做什么"
fmt.Printf("p = %v \n", p)
}
比较运算
//比较每个成员是否相等
func compare() {
b1 := Books{8, "云战略", "徐欢生", "传统企业如何借助互联网转型"}
b2 := Books{8, "云战略", "徐欢生", "传统企业如何借助互联网转型"}
b3 := Books{8, "云战略", "徐老师", "传统企业如何借助互联网转型"}
fmt.Printf("b1 == b2 is %v \n", b1 == b2)
fmt.Printf("b1 == b3 is %v \n", b1 == b3)
fmt.Printf("b1 != b3 is %v \n", b1 != b3)
}
结构体变量作为函数参数传递
-
值传递
-
指针(引用)传递
//结构体作为函数参数传递1 - 值传递,形参无法修改实参
func referenceByParam(book Books) {
book.bookSubject = "人与人之间最小的差别是智商,最大的差别是坚持"
fmt.Printf("book's info is %v \n", book)
}
//结构体作为函数参数传递1 - 指针传递
func referenceByParam2(book *Books) {
book.bookSubject = "人与人之间最小的差别是智商,最大的差别是坚持"
fmt.Printf("book's info is %v \n", book)
}
func main() {
//普通的结构体变量作为参数传递,形参不能改实参
book := Books{9, "扛得住,世界就是你的", "小川叔", "工作职场的经验分享"}
referenceByParam(book)
fmt.Printf("book's info is %v \n", book)
//指针结构体变量作为参数传递,引用可以改实参
referenceByParam2(&book)
fmt.Printf("book's info is %v \n", book)
}
支持匿名结构,可以用作结构成员或定义变量
type File struct {
name string
size int
attr struct {
perm int
owner int
}
}
func initFileObj() {
file := File{
name: "test.txt",
size: 1025,
// attr: {0755, 1}, //Error: missing type in composite literal
}
file.attr.owner = 1
file.attr.perm = 0755
fmt.Printf("file's value is %v \n", file)
//另外一种方式 对attr 进行赋值
var attr = struct {
perm int
owner int
}{
0755, 2,
}
file.attr = attr
fmt.Printf("file's value is %v \n", file)
}
指向自身类型的指针成员
type Node struct {
id int
data *byte
next *Node
}
func main() {
nodeOne := Node{
id: 1,
data: nil,
}
//结构体支持指向自身类型的指针成员
nodeTwo := Node{
id: 2,
data: nil,
next: &nodeOne,
}
fmt.Printf("nodeOne : %v \n, nodeTwo : %v \n", nodeOne, nodeTwo)
}