Go学习(9):结构体 2022-04-18 06:09 92阅读 0赞 # 一、结构体 # ## 1.1 什么是结构体 ## Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是由一系列具有相同类型或不同类型的数据构成的数据集合。 ## 1.2 结构体的定义和初始化 ## type struct_variable_type struct { member definition; member definition; ... member definition; } 一旦定义了结构体类型,它就能用于变量的声明 variable_name := structure_variable_type { value1, value2...valuen} **初始化结构体** // 1.按照顺序提供初始化值 P := person{ "Tom", 25} // 2.通过field:value的方式初始化,这样可以任意顺序 P := person{ age:24, name:"Tom"} // 3.new方式,未设置初始值的,会赋予类型的默认初始值 p := new(person) p.age=24 ## 1.3 结构体的访问 ## 访问结构体成员(访问结构的各个字段) 通过点.操作符用于访问结构的各个字段。 package main import "fmt" type Books struct { title string author string subject string book_id int } func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ var Book2 Books /* 声明 Book2 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* book 2 描述 */ Book2.title = "Python 教程" Book2.author = "www.runoob.com" Book2.subject = "Python 语言教程" Book2.book_id = 6495700 /* 打印 Book1 信息 */ fmt.Printf( "Book 1 title : %s\n", Book1.title) fmt.Printf( "Book 1 author : %s\n", Book1.author) fmt.Printf( "Book 1 subject : %s\n", Book1.subject) fmt.Printf( "Book 1 book_id : %d\n", Book1.book_id) /* 打印 Book2 信息 */ fmt.Printf( "Book 2 title : %s\n", Book2.title) fmt.Printf( "Book 2 author : %s\n", Book2.author) fmt.Printf( "Book 2 subject : %s\n", Book2.subject) fmt.Printf( "Book 2 book_id : %d\n", Book2.book_id) } 运行结果: Book 1 title : Go 语言 Book 1 author : www.runoob.com Book 1 subject : Go 语言教程 Book 1 book_id : 6495407 Book 2 title : Python 教程 Book 2 author : www.runoob.com Book 2 subject : Python 语言教程 Book 2 book_id : 6495700 ## 1.4 结构体指针 ## 指针指向一个结构体 也可以创建指向结构的指针。 **结构体指针** var struct_pointer *Books 以上定义的指针变量可以存储结构体变量的地址。查看结构体变量地址,可以将 & 符号放置于结构体变量前 struct_pointer = &Book1; 使用结构体指针访问结构体成员,使用 “.” 操作符 struct_pointer.title; package main import "fmt" type Books struct { title string author string subject string book_id int } func main() { var Book1 Books /* Declare Book1 of type Book */ var Book2 Books /* Declare Book2 of type Book */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* book 2 描述 */ Book2.title = "Python 教程" Book2.author = "www.runoob.com" Book2.subject = "Python 语言教程" Book2.book_id = 6495700 /* 打印 Book1 信息 */ printBook(&Book1) /* 打印 Book2 信息 */ printBook(&Book2) } func printBook( book *Books ) { fmt.Printf( "Book title : %s\n", book.title); fmt.Printf( "Book author : %s\n", book.author); fmt.Printf( "Book subject : %s\n", book.subject); fmt.Printf( "Book book_id : %d\n", book.book_id); } 结构体实例化也可以是这样的 package main import "fmt" type Books struct { } func (s Books) String() string { return "data" } func main() { fmt.Printf("%v\n", Books{ }) } ## 1.5 结构体的匿名字段 ## **结构体的匿名字段** 可以用字段来创建结构,这些字段只包含一个没有字段名的类型。这些字段被称为匿名字段。 在类型中,使用不写字段名的方式,使用另一个类型 type Human struct { name string age int weight int } type Student struct { Human // 匿名字段,那么默认Student就包含了Human的所有字段 speciality string } func main() { // 我们初始化一个学生 mark := Student{ Human{ "Mark", 25, 120}, "Computer Science"} // 我们访问相应的字段 fmt.Println("His name is ", mark.name) fmt.Println("His age is ", mark.age) fmt.Println("His weight is ", mark.weight) fmt.Println("His speciality is ", mark.speciality) // 修改对应的备注信息 mark.speciality = "AI" fmt.Println("Mark changed his speciality") fmt.Println("His speciality is ", mark.speciality) // 修改他的年龄信息 fmt.Println("Mark become old") mark.age = 46 fmt.Println("His age is", mark.age) // 修改他的体重信息 fmt.Println("Mark is not an athlet anymore") mark.weight += 60 fmt.Println("His weight is", mark.weight) } > 可以使用"."的方式进行调用匿名字段中的属性值 > > 实际就是字段的继承 > > 其中可以将匿名字段理解为字段名和字段类型都是同一个 > > 基于上面的理解,所以可以`mark.Human = Human{"Marcus", 55, 220}`和`mark.Human.age -= 1` > > 若存在匿名字段中的字段与非匿名字段名字相同,则最外层的优先访问,就近原则 通过匿名访问和修改字段相当的有用,但是不仅仅是struct字段哦,所有的内置类型和自定义类型都是可以作为匿名字段的。 ## 1.6 结构体嵌套 ## 嵌套的结构体 一个结构体可能包含一个字段,而这个字段反过来就是一个结构体。这些结构被称为嵌套结构。 示例代码: package main import ( "fmt" ) type Address struct { city, state string } type Person struct { name string age int address Address } func main() { var p Person p.name = "Naveen" p.age = 50 p.address = Address { city: "Chicago", state: "Illinois", } fmt.Println("Name:", p.name) fmt.Println("Age:",p.age) fmt.Println("City:",p.address.city) fmt.Println("State:",p.address.state) } ## 1.7 提升字段 ## 在结构体中属于匿名结构体的字段称为提升字段,因为它们可以被访问,就好像它们属于拥有匿名结构字段的结构一样。理解这个定义是相当复杂的。 示例代码: package main import ( "fmt" ) type Address struct { city, state string } type Person struct { name string age int Address } func main() { var p Person p.name = "Naveen" p.age = 50 p.Address = Address{ city: "Chicago", state: "Illinois", } fmt.Println("Name:", p.name) fmt.Println("Age:", p.age) fmt.Println("City:", p.city) //city is promoted field fmt.Println("State:", p.state) //state is promoted field } 运行结果 Name: Naveen Age: 50 City: Chicago State: Illinois ## 1.8 导出结构体和字段 ## 如果结构体类型以大写字母开头,那么它是一个导出类型,可以从其他包访问它。类似地,如果结构体的字段以大写开头,则可以从其他包访问它们。 示例代码: 1.在computer目录下,创建文件spec.go package computer type Spec struct { //exported struct Maker string //exported field model string //unexported field Price int //exported field } 2.创建main.go 文件 package main import "structs/computer" import "fmt" func main() { var spec computer.Spec spec.Maker = "apple" spec.Price = 50000 fmt.Println("Spec:", spec) } > 目录结构如下: > > src > structs > computer > spec.go > main.go ## 1.9 结构体比较 ## 结构体是值类型,如果每个字段具有可比性,则是可比较的。如果它们对应的字段相等,则认为两个结构体变量是相等的。 示例代码: package main import ( "fmt" ) type name struct { firstName string lastName string } func main() { name1 := name{ "Steve", "Jobs"} name2 := name{ "Steve", "Jobs"} if name1 == name2 { fmt.Println("name1 and name2 are equal") } else { fmt.Println("name1 and name2 are not equal") } name3 := name{ firstName:"Steve", lastName:"Jobs"} name4 := name{ } name4.firstName = "Steve" if name3 == name4 { fmt.Println("name3 and name4 are equal") } else { fmt.Println("name3 and name4 are not equal") } } 运行结果 name1 and name2 are equal name3 and name4 are not equal **如果结构变量包含的字段是不可比较的,那么结构变量是不可比较的** 示例代码: package main import ( "fmt" ) type image struct { data map[int]int } func main() { image1 := image{ data: map[int]int{ 0: 155, }} image2 := image{ data: map[int]int{ 0: 155, }} if image1 == image2 { fmt.Println("image1 and image2 are equal") } } ## 2.0 结构体作为函数的参数 ## 结构体作为函数参数使用 ackage main import "fmt" type Books struct { title string author string subject string book_id int } func main() { var Book1 Books /* 声明 Book1 为 Books 类型 */ var Book2 Books /* 声明 Book2 为 Books 类型 */ /* book 1 描述 */ Book1.title = "Go 语言" Book1.author = "www.runoob.com" Book1.subject = "Go 语言教程" Book1.book_id = 6495407 /* book 2 描述 */ Book2.title = "Python 教程" Book2.author = "www.runoob.com" Book2.subject = "Python 语言教程" Book2.book_id = 6495700 /* 打印 Book1 信息 */ printBook(Book1) /* 打印 Book2 信息 */ printBook(Book2) } func printBook( book Books ) { fmt.Printf( "Book title : %s\n", book.title); fmt.Printf( "Book author : %s\n", book.author); fmt.Printf( "Book subject : %s\n", book.subject); fmt.Printf( "Book book_id : %d\n", book.book_id); } **make、new操作** make用于内建类型(map、slice 和channel)的内存分配。new用于各种类型的内存分配 内建函数new本质上说跟其它语言中的同名函数功能一样:new(T)分配了零值填充的T类型的内存空间,并且返回其地址,即一个\*T类型的值。用Go的术语说,它返回了一个指针,指向新分配的类型T的零值。有一点非常重要:new返回指针 内建函数make(T, args)与new(T)有着不同的功能,make只能创建slice、map和channel,并且返回一个有初始值(非零)的T类型,而不是\*T。本质来讲,导致这三个类型有所不同的原因是指向数据结构的引用在使用前必须被初始化。例如,一个slice,是一个包含指向数据(内部array)的指针、长度和容量的三项描述符;在这些项目被初始化之前,slice为nil。对于slice、map和channel来说,make初始化了内部的数据结构,填充适当的值。 make返回初始化后的(非零)值。 -------------------- 整理自菜鸟教程
相关 go中结构体和结构体变量 一 结构体和结构体变量的区别和联系 1 结构体是自定义的数据类型,代表一类事物。 2 结构体变量(实例)是具体的,实际的,代表一个具体变量。 二 结构体变量在内存的 野性酷女/ 2021年07月24日 19:22/ 0 赞/ 374 阅读
相关 go的结构体变量和结构体字段 一 创建结构体变量和访问结构体字段 1 定义 a 方式1:直接声明 > var person Person b方式2:结构体类型\{\} > var pers ﹏ヽ暗。殇╰゛Y/ 2021年07月24日 20:31/ 0 赞/ 429 阅读
相关 go学习笔记(3结构体) 转载:[http://www.runoob.com/go/go-structures.html][http_www.runoob.com_go_go-structures.ht 女爷i/ 2022年02月25日 17:58/ 0 赞/ 88 阅读
相关 Go 结构体,定义结构体类型,struct demo.go(定义结构体类型): package main import "fmt" // 定义结构体类型 (在函数外部定 小鱼儿/ 2022年03月02日 04:10/ 0 赞/ 209 阅读
相关 Go学习(9):结构体 一、结构体 1.1 什么是结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型。 结构体是由一系列具有相同类型或不同类 亦凉/ 2022年04月18日 06:09/ 0 赞/ 93 阅读
相关 GO语言笔记--结构体 1.说明 1)go中的struct与C中的struct非常相似,并且go没有class 2)使用type <Name> struct \{\}定义结构,名称遵循可见性规 旧城等待,/ 2022年04月25日 04:58/ 0 赞/ 115 阅读
相关 GO学习笔记(结构体) go 可以像c 语言一样使用struct 定义结构体 > go 结构体定义和使用 type cat struct { // 结构体内容 素颜马尾好姑娘i/ 2022年05月27日 12:37/ 0 赞/ 97 阅读
相关 C语言学习笔记9--结构体 定义一个结构的一般形式为: struct 结构名 \{ 成员表列 \}; 对每个成员也必须作类型说明,其形式为: 类型说明符 成员名; struct stude 左手的ㄟ右手/ 2022年08月27日 05:53/ 0 赞/ 101 阅读
相关 Go 学习笔记 08 | 结构体详解 一、结构体 实例化结构体 第一种实例化结构体:var 变量 结构体 package main import ( "fmt" 分手后的思念是犯贱/ 2022年12月23日 03:52/ 0 赞/ 66 阅读
还没有评论,来说两句吧...