最近疫情比较严重,过年也不能出门,闲来无事,继续更新博客吧。
武汉加油!
我们来继续说下go语言中的结构体
比如我们现在想存储一个学生信息,如:学号、姓名、年龄、性别,等信息,按照我们以前的存储习惯,将分别定义各个类型的字段,来表示不同的字段,不同的数据类型。
通过以往的定义形式进行存储,这种方法可行,但是相对来说,比较麻烦,且不利于数据的管理。
但是在GO语言中,我们可以通过结构体的形式来存储数据,下面我们看下,结构体的定义:
package main
import "fmt"
//在函数外部定义结构体,作用全局。
//结构体定义
//type 名称 struct {
//结构体成员列表
//}
type Student struct {
id int
name string
sex string
age int
addr string
}
func main() {
//通过结构体名, 定义结构体变量
var stdu Student
//结构体变量名.成员名称
stdu.id = 111
stdu.name = "张三"
stdu.sex = "男"
stdu.age = 26
stdu.addr = "成都"
fmt.Println(stdu)
}
输出结果:
{111 张三 男 26 成都}
另外一种定义方式:
在写结构体参数时,固定按照定义的结构体顺序来写
func main() {
var stdu Student=Student{111,"张三", "男", 28, "成都"}
fmt.Println(stdu)
}
我们在看看自动推导类型如何定义结构体
stdu_1:= Student{age:26, id:222, name:"李四", addr:"成都", sex:"男"}
我们在使用自动推导类型定义结构体的时候,需要将结构体中的参数添加在定义变量之前。
二、结构体的赋值和比较
package main
import "fmt"
type Student struct {
id int
name string
sex string
age int
addr string
}
func main() {
s:= Student{1, "啦啦", "男", 18, "成都"}
//结构体变量赋值
s1:=s
fmt.Println(s1)
//改变结构体中的值
s1.age=26
fmt.Println(s1)
//我们看看,修改的值,会不会影响我们原来的s
fmt.Println(s)
}
结果:
{1 啦啦 男 18 成都}
{1 啦啦 男 26 成都}
{1 啦啦 男 18 成都}
我们可以看到,我们将结构体s赋值给s1打印,s1,得到跟s结构体一样的信息
在将,s1的年龄更改至26岁,打印s1, 打印s,可以看到,修改s1的值,不会更改s的值.。
结构体比较
//在结构体中,比较操作,使用“==”或者“!=”来比较,不能大于小于等。
if s1!=s{
fmt.Println("不相同")
}else {
fmt.Println("相同")
}
结果:
不相同
在结构体中,只能使用“==”或“!=”进行比较,不可以使用大于、小于等作为结构体的比较。
大于小于,可以用于对结构体成员进行比较。
if s.age>s1.age{
fmt.Println("s的年龄,大于s1的年龄")
}else {
fmt.Println("s的年龄,小于s1的年龄")
}
结果:
s的年龄,小于s1的年龄
三、结构体数组切片的定义于使用
前面我们已经对结构体的定义,与基本使用做了一定的介绍。
1、结构体数组
package main
import "fmt"
type student struct {
id int
name string
sex string
age int
score int
addr string
}
func main() {
//var 结构体变量名 结构体类型
//定义结构体数组
//var 结构体数组名[元素个数] 结构体类型
var arr[5]student
// len(数组名)计算数组元素个数
//fmt.Println(len(arr))
for i:=0; i<len(arr) ;i++{
fmt.Scan(&arr[i].id,&arr[i].name,&arr[i].sex,&arr[i].age,&arr[i].score,&arr[i].addr)
}
fmt.Println(arr)
}
结果:
1 哈哈 男 18 88 成都
2 啦啦 女 16 99 北京
3 呆呆 男 17 77 上海
4 哒哒 女 15 66 广州
5 嘎嘎 男 14 55 深圳
[{1 哈哈 男 18 88 成都} {2 啦啦 女 16 99 北京} {3 呆呆 男 17 77 上海} {4 哒哒 女 15 66 广州} {5 嘎嘎 男 14 55 深圳}]
输入上面的数据,打印结构体数组得到的内容。
通过循环方式,输出结构体数据内容
//fmt.Println(arr)
//通过循环方式,将结构体的每一项输出
for i:=0; i<len(arr); i++ {
fmt.Println(arr[i])
}
结果:
1 哈哈 男 18 88 成都
2 啦啦 女 16 99 北京
3 呆呆 男 17 77 上海
4 哒哒 女 15 66 广州
5 嘎嘎 男 14 55 深圳
{1 哈哈 男 18 88 成都}
{2 啦啦 女 16 99 北京}
{3 呆呆 男 17 77 上海}
{4 哒哒 女 15 66 广州}
{5 嘎嘎 男 14 55 深圳}
2、根据结构体成员信息进行排序操作(冒泡排序算法)
package main
import "fmt"
type student struct {
id int
name string
sex string
age int
score int
addr string
}
func main() {
//var 结构体变量名 结构体类型
//定义结构体数组
//var 结构体数组名[元素个数] 结构体类型
var arr[5]student
// len(数组名)计算数组元素个数
//fmt.Println(len(arr))
for i:=0; i<len(arr) ;i++{
fmt.Scan(&arr[i].id,&arr[i].name,&arr[i].sex,&arr[i].age,&arr[i].score,&arr[i].addr)
}
//fmt.Println(arr)
//通过循环方式,将结构体的每一项输出
fmt.Println("排序前:")
for i:=0; i<len(arr); i++ {
fmt.Println(arr[i])
}
//根据结构体成员信息进行排序操作,使用冒泡排序算法
for i:=0; i< len(arr)-1; i++{
for j:=0;j<len(arr)-1-i;j++{
//比较结构体成员信息,年龄,成绩均可以进行排序
if arr[j].age>arr[j+1].age{
//通过比较交换成员
arr[j],arr[j+1]=arr[j+1],arr[j]
}
}
}
fmt.Println("排序后:")
for i:=0; i<len(arr); i++ {
fmt.Println(arr[i])
}
}
结果:
1 哈哈 男 18 88 成都
2 啦啦 女 16 99 北京
3 呆呆 男 17 77 上海
4 哒哒 女 15 66 广州
5 嘎嘎 男 14 55 深圳
排序前:
{1 哈哈 男 18 88 成都}
{2 啦啦 女 16 99 北京}
{3 呆呆 男 17 77 上海}
{4 哒哒 女 15 66 广州}
{5 嘎嘎 男 14 55 深圳}
排序后:
{5 嘎嘎 男 14 55 深圳}
{4 哒哒 女 15 66 广州}
{2 啦啦 女 16 99 北京}
{3 呆呆 男 17 77 上海}
{1 哈哈 男 18 88 成都}
数组中的元素,允许相互赋值操作,将结构体成员中的所有数据进行相互交换。
3、使用自动类型推导,创建结构体
package main
import "fmt"
type students struct {
id int
name string
sex string
age int
score int
addr string
}
func main() {
//使用自动类型推导创建结构体信息
arr:=[3]students{
{101,"啦啦","男", 50, 99,"成都"},
{102,"哈哈","女",40,100,"北京"},
{103,"嘎嘎", "男",30,88,"上海"},
}
for i,v:=range arr{
//打印类型
//fmt.Printf("%T",v)
fmt.Println(i,v)
}
}
结果:
0 {101 啦啦 男 50 99 成都}
1 {102 哈哈 女 40 100 北京}
2 {103 嘎嘎 男 30 88 上海}
4、切片结构体定义:
区别:[元素个数] 数组 []切片
arr:=[]students{
{101,"啦啦","男", 50, 99,"成都"},
{102,"哈哈","女",40,100,"北京"},
{103,"嘎嘎", "男",30,88,"上海"},
}
一样可以进行打印运行。
package main
import "fmt"
type students struct {
id int
name string
sex string
age int
score int
addr string
}
func main() {
//使用自动类型推导创建结构体信息
// [元素个数] 数组 [] 切片
arr:=[]students{
{101,"啦啦","男", 50, 99,"成都"},
{102,"哈哈","女",40,100,"北京"},
{103,"嘎嘎", "男",30,88,"上海"},
}
//在切片中添加数据信息
arr = append(arr,students{104,"哒哒", "男",40,77,"广州"})
for i,v:=range arr{
//打印类型
//fmt.Printf("%T",v)
fmt.Println(i,v)
}
}
结果:
0 {101 啦啦 男 50 99 成都}
1 {102 哈哈 女 40 100 北京}
2 {103 嘎嘎 男 30 88 上海}
3 {104 哒哒 男 40 77 广州}
四、结构体作为Map中的值
package main
import "fmt"
type stu struct {
name string
age int
score int
}
func main() {
//定义一个map
m:=make(map[int]stu)
m[1] = stu{"哈哈", 50,88}
m[2] = stu{"哒哒",51,88}
fmt.Println(m)
}
结果:
map[1:{哈哈 50 88} 2:{哒哒 51 88}]
使用循环遍历map中的值
for k,v:=range m{
fmt.Println(k,v)
}
结果:
1 {哈哈 50 88}
2 {哒哒 51 88}
五、结构体切片作为map中的值
package main
import "fmt"
type stu struct {
name string
age int
score int
}
func main() {
//结构体切片作为map中的值
m:=make(map[int][]stu)
// map结构体切片赋值
m[1] = append(m[1],stu{"哈哈1",51,81},
stu{"哒哒1",61,91})
m[2] = append(m[2],stu{"哈哈2",52,82},
stu{"哒哒2",62,82})
m[3] = append(m[3],stu{"哈哈3",53,83},
stu{"哒哒3",63,93})
//遍历操作
for k,v:=range m{
//此时,V的类型为,结构体切片。
//在遍历切片信息
for i,data:=range v{
fmt.Println("key:",k,"index:",i,"value:",data)
}
}
}
结果:
key: 1 index: 0 value: {哈哈1 51 81}
key: 1 index: 1 value: {哒哒1 61 91}
key: 2 index: 0 value: {哈哈2 52 82}
key: 2 index: 1 value: {哒哒2 62 82}
key: 3 index: 0 value: {哈哈3 53 83}
key: 3 index: 1 value: {哒哒3 63 93}
六、结构体作为函数参数
package main
import "fmt"
type person struct {
id int
name string
score int
sex string
}
func test(s person){
fmt.Println(s.name)
fmt.Println(s.score)
fmt.Println(s.sex)
}
func main() {
stu:=person{1,"哈哈", 55,"男"}
//结构体作为函数参数
test(stu)
}
结果:
哈哈
55
男
结构体作为函数参数是值传递
package main
import "fmt"
type person struct {
id int
name string
score int
sex string
}
func test(s person){
s.name = "哒哒哒"
}
func main() {
stu:=person{1,"哈哈", 55,"男"}
//结构体作为函数参数
test(stu)
//结构体作为函数参数,是值传递。
fmt.Println(stu)
}
结果:没有改变结构体名称,值传递。
值传递,形参单元和实参单元是不同的存储区域,修改不会影响其他的值。(这里注意,所有的切片类型,都为地址传递)
{1 哈哈 55 男}
结构体切片,作为参数地址传递。
package main
import "fmt"
type person struct {
id int
name string
score int
sex string
}
//所有的切片,都是地址传递
func test(stu []person){
stu[0].name = "哒哒"
}
func main() {
//定义结构体切片
stu:=[]person{{1,"哈哈", 55,"男"},
{2,"啦啦", 88,"女"}}
//为切片添加数据
stu = append(stu,person{3,"嘎嘎",66,"男"})
//结构体切片作为函数参数是地址传递
//结构体数组作为函数参数是值传递
test(stu)
fmt.Println(stu)
}
结果:
[{1 哒哒 55 男} {2 啦啦 88 女} {3 嘎嘎 66 男}]