funcmain(){// 成员名称前面不能添加vartype Student struct{
id int
name string
age int
addr string}// 顺序初始化var s Student = Student{101,"张三",18,"北京"}
fmt.Println(s)// 指定成员初始化,部分初始化var s1 Student = Student{name:"李四", age:18}
fmt.Println(s1)// 通过“结构体变量.成员” 完成初始化var stu Student
stu.id =102
stu.name ="老王"
stu.age =28
stu.addr ="北京"
fmt.Println(stu)}
2 - 结构体数组
结构体数组定义:var 结构体数组名 [下标] 结构体类型
修改结构体数组成员的值:结构体数组名[下标].成员=值
结构体数组遍历
for…len() 进行遍历
for…range 进行遍历
type Student struct{
id int
name string
age int
addr string}funcmain(){var arr [3]Student =[3]Student{
Student{101,"张三",18,"北京"},
Student{102,"李四",18,"北京"},
Student{103,"王五",19,"北京"},}
fmt.Println(arr)
fmt.Println(arr[0])
fmt.Println(arr[0].age)
arr[0].age =20
fmt.Println(arr)// 通过循环来输出结构体数组中的内容。for i :=0; i <len(arr); i++{
fmt.Println(arr[i].age)}for k, v :=range arr {
fmt.Println(k)
fmt.Println(v.age)}}
3 - 结构体切片
结构体切片定义:var 结构体切片名 [ ] 结构体类型
修改结构体切片成员的值:结构体切片名[下标].成员=值
结构体切片遍历
for…len() 进行遍历
for…range 进行遍历
append函数使用:向结构体切片末尾追加数据
type Student struct{
id int
name string
age int
addr string}funcmain(){var s []Student =[]Student{
Student{101,"张三",18,"北京"},
Student{102,"李四",18,"北京"},}
fmt.Println(s[0])
fmt.Println(s[0].age)
s[0].age =20
fmt.Println(s)// 循环遍历for i :=0; i <len(s); i++{
fmt.Println(s[i].name)}for k, v :=range s {
fmt.Println(k)
fmt.Println(v.id)}// 追加数据
s =append(s, Student{103,"王五",20,"北京"})
fmt.Println(s)}
4 - 结构体map
结构体map定义:make(map[key的类型]值的类型)
结构体map初始化:map名字[键]=值
结构体map循环遍历:通过for…range方式进行遍历
删除map中的值:delete(map名字,键)
type Student struct{
id int
name string
age int
addr string}funcmain(){
m :=make(map[int]Student)
m[1]= Student{101,"张三",18,"北京"}
m[2]= Student{102,"李四",18,"北京"}
fmt.Println(m)
fmt.Println(m[1])
fmt.Println(m[1].name)delete(m,2)
fmt.Println(m)for key, value :=range m {
fmt.Println(key)
fmt.Println(value.age)}}
5 - 结构体作为函数参数
结构体作为函数参数:在函数中修改结构体成员值,不会影响到原结构体
type Student struct{
id int
name string
age int
addr string}funcmain(){
stu := Student{101,"张三",18,"北京"}PrintDemo(stu)
fmt.Println(stu)// {101 张三 18 北京}}funcPrintDemo(stu Student){
stu.age =20
fmt.Println(stu)// {101 张三 20 北京}}
funcmain(){var a int=10var p *int
p =&a
fmt.Printf("%p\n",&a)// 0xc00000a0a8
fmt.Printf("%p\n", p)// 0xc00000a0a8
fmt.Printf("%p\n",&p)// 0xc000006028
fmt.Println(*p)// 10*p =222
fmt.Println("a=", a)// 222}
2 - 指针操作注意事项
空指针
funcmain(){var p *int
fmt.Println(p)// <nil>}
不要操作没有合法指向的内存
funcmain(){var p *int*p =78}
new函数使用:开辟数据类型对应的内存空间,返回值为数据类型指针
funcmain(){var p *int
p =new(int)*p =67
fmt.Println(*p)}
3 - 指针变量作为函数参数
funcmain(){var num int=10Update(&num)
fmt.Println(num)}funcUpdate(p *int){*p =60}
4 - 数组指针
数组指针定义:var 数组指针变量 *[下标] 类型
funcmain(){
nums :=[10]int{1,2,3,4,5,6,7,8,9,10}var p *[10]int
p =&nums
fmt.Println(*p)// 获取整个数组中的内容,[1 2 3 4 5 6 7 8 9 10]
fmt.Println((*p)[3])// []的运算优先级高于*,4
fmt.Println(p[0])// 1for i :=0; i <len(p); i++{
fmt.Println(p[i])}UpdateArr(p)
fmt.Println(nums)}funcUpdateArr(p *[10]int){
p[0]=100}
5 - 指针数组
指针数组概念:数组元素是指针类型
指针数组指的是一个数组中存储的都是指针(也就是地址)。也就是一个存储了地址的数组
指针数组定义语法:var 数组名 [下标]*类型
指针数组根据具体地址获取对应的值:* 指针数组名[下标]
funcmain(){var p [2]*intvar i int=10var j int=20
p[0]=&i
p[1]=&j
fmt.Println(p)
fmt.Println(*p[0])// 不要加括号
fmt.Println(*p[1])//循环for i :=0; i <len(p); i++{
fmt.Println(*p[i])}for k, value :=range p {
fmt.Println(k)
fmt.Println(*value)}}
6 - 切片指针
切片指针概念:定义指针,指向切片
funcmain(){
s :=[]int{1,2,3,4,5,6}var p *[]int
p =&s
fmt.Println(*p)
fmt.Println((*p)[0])//fmt.Println(p[0]) //错误,这个与数组指针不同// 切片指针修改切片的元素(*p)[0]=200
fmt.Println(s)//切片指针遍历for i :=0; i <len(*p); i++{
fmt.Println((*p)[i])}for k, value :=range*p {
fmt.Println("k=", k)
fmt.Println("value=", value)}}
7 - 结构体指针
结构体指针概念:定义指针,指向结构体
结构体指针作为函数:在函数中修改结构体的成员的值,会影响原结构体成员的值
type Student struct{
id int
name string
age int}funcmain(){
stu := Student{101,"张三",18}var p *Student
p =&stu
fmt.Println(*p)
fmt.Println((*p).name)
fmt.Printf("p.name=%s\n", p.name)// 简化的结构体指针写法// 修改结构体中的值
p.age =20
fmt.Println(stu)// {101 张三 20}UpdateStruct(p)
fmt.Println(stu)// {101 张三 21}}funcUpdateStruct(stu *Student){
stu.age =21}
8 - 多级指针(简单了解)
funcmain(){var a int=10var p *int//一级指针
p =&a
var pp **int
pp =&p
**pp =200
fmt.Println(a)// 200}
三、基础加强
1 - 深浅拷贝
浅拷贝:仅仅拷贝的是变量的值,没有对指向的空间进行任何的拷贝
深拷贝:将原有的变量的空间全部拷贝一份(GO语言几乎很少用到)
函数传参是浅拷贝
funcmain(){var num int=10
ap :=&num
Update(ap)
fmt.Println(num)}funcUpdate(p *int){*p =60}
funcmain(){
v :=[3]int{1,2,3}for i, value :=range(v){//对形参进行遍历
v[i]=3// 输出打印遍历值
fmt.Println("value:", value)// 1 2 3}// 打印切片的值
fmt.Println("v", v)// v [3 3 3]}
修改range得到后的value,不影响原始切片或者数组
type Student struct{
Name string
Age int}funcmain(){// 定义一个student 类型切片
stu1 := Student{"MrWang",100}
stu2 := Student{"MrSun",50}
stu3 := Student{"MrQiu",25}
v :=[]Student{stu1, stu2, stu3}// 循环遍历 数组for_, value :=range v {
value.Age = value.Age +1000// 对每个人的年龄进行更新}// 打印切片的值
fmt.Println(v)// [{MrWang 100} {MrSun 50} {MrQiu 25}]}