Go 语言中数组切片可以存储同一类型的数据,那当我们需要存储一些不同数据类型的集合时候该怎么办呢?自然而然的就引出了 结构体 。在结构体中可以为不同项定义 不同的数据类型 。结构体是由一系列具有不同类型的数据构成的数据集合。
type 结构体名 struct {
结构体成员名 数据类型
结构体成员名 数据类型
结构体成员名 数据类型
}
要注意结构体成员在定义时不能够直接赋值!
比如我们可以定义一个学生结构体,要求存储姓名、年龄、性别、分数、地址这些信息。
type student struct {
name string
age int
sex string
score int
addr string
}
4.1结构体初始化
结构体在定义之后也需要定义结构体变量,他也是一种数据类型,只不过这个数据类型比较特殊,是我们自己定义的数据类型。
//结构体变量
var 结构体变量名 结构体数据类型
在定义结构体变量后可以为结构体成员进行初始化
var zhangsan student = student{"张三", 18, "男", 100, "上海"}
然后就可以对我们的结构体变量进行操作啦!
完整实例:
package main
import "fmt"
type Books struct {
title string
author string
price float32
}
func main() {
book := Books{
title: "c语言教程",
author: "谭浩强",
price: 123.4,
}
fmt.Printf(book.title)
fmt.Printf(book.author)
fmt.Printf("%f", book.price)
print("=========================")
var book1 Books
var book2 Books
book1.title = "1111"
book1.author = "zhangsan"
book1.price = 12.33
book2.title = "2222"
book2.author = "lisi"
book2.price = 14.44
/* 打印 Book1 信息 */
fmt.Printf("Book 1 title : %s\n", book1.title)
fmt.Printf("Book 1 author : %s\n", book1.author)
fmt.Printf("Book 1 price : %d\n", &book1.price)
/* 打印 Book2 信息 */
fmt.Printf("Book 2 title : %s\n", book2.title)
fmt.Printf("Book 2 author : %s\n", book2.author)
fmt.Printf("Book 2 price : %f\n", book2.price)
}
4.2 结构体切片
定义结构体变量只能存储一条结构体信息,但是当我们有存储多个信息的时候该怎么处理呢?自然就引出了结构体数组或者切片。
//结构体切片 var 结构体切片名 []结构体数据类型 //例如 var students []Stu //Stu是一个结构体类型 /*type Stu struct { name string age int sex string score int addr string }*/
代码实例:
package main
import (
"fmt"
)
type Stu struct {
name string
age int
sex string
}
func main() {
var students []Stu = []Stu{
Stu{name: "tom", age: 18, sex: "男"},
Stu{name: "jack", age: 18, sex: "男"},
Stu{name: "rose", age: 18, sex: "女"}}
fmt.Printf("%v\n", students)
//切片扩容
students = append(students, Stu{"李四", 16, "男"})
fmt.Printf("%v", students)
//遍历打印
for _, student := range students {
fmt.Printf("%v", student)
}
}
4.3 匿名字段
可以通过匿名字段实现 “ 继承关系 ” ,所谓的匿名字段就是 将结构体名称作为另外结构体的成员 。 虽然在go中没有所谓的OOP,没有这些封装继承多态但是可以通过一些“手段”来实现类似的效果,看上去就像是OOP一样。至于“多态”就在后面的学习笔记中提到。
- 当“子类”结构体将“父类”结构体作为匿名结构体放在“肚子”里的时候,“子类”就会自动获得父类的“属性”
package main
import "fmt"
//子类和父类有共同的成员名
type People struct {
Name string
Age int
}
type Student1 struct {
//匿名字段 将结构体作为另外一个结构体成员
People
Score int
}
func main() {
stu := Student1{People{"兵哥", 18}, 100}
//注意这里我们可以直接在stu下.出来我们的Name属性 其实这是go语言的一种优化吧
//在使用的时候就省去了stu.people.Name的繁琐操作 在使用的时候就像我们熟悉的继承机制
fmt.Println(stu.Name)
}
- 当“子类”中有父类同样的属性的时候我们在访问的时候采取的是就近原则也就是访问的是我们在子类中定义的属性,而“父类”的属性。
注意:这里我说说的“子类”、“父类”只是为了方便理解、有利于表达来的,在go中是没有这些概念的。
到这里是不是觉得我们的go语言也很有趣呢?OOP也还没有介绍完呢。在介绍完方法之后还会有更有趣的“重写”。