GO语言基础-03

数组

数组:具有相同类型的⼀一组⻓长度固定 的数据序列列
声明语法 :var 变量量名 [数组⻓长度] 数据类型

import "fmt"

func main() {
	fmt.Println("数组测试。。。")

	//方式1:定义定长数组并完成初始化
	var arr0 = [3]float64 {2.1, 3.2, 4.6}
	fmt.Println(arr0)
	fmt.Println("-----------")

	//方式2:定义数组,后完成初始化
	var arr1 [3]int
	arr1[0], arr1[1], arr1[2]  = 1, 2, 3
	fmt.Println(arr1)
	fmt.Println("-----------")

	//方式3:初始化定义数组,并自动推导长度
	var arr2 = [...]byte{1,2,3}
	fmt.Println(arr2)

	//数组地址,可观察到,数组中地址连续
	fmt.Println(&arr2[0])  //0xc0000160e0
	fmt.Println(&arr2[1])  //0xc0000160e1
	fmt.Println(&arr2[2])  //0xc0000160e2
}

切片

可理解为变长数组。
切⽚片本身没有任何数据,只是对现有数组的引⽤。
slice三要素:

  • 指针:指向数组中slice指定的开始位置
  • 长度:即slice的长度
  • 最大长度:slice开始位置到数组最后位置的长度

声明语法:var identifier []type

切片声明
import "fmt"

func main(){
	//方式1:自动推导类型
	s1 := []int{1,2,3}   //定义切片
	fmt.Println(s1)

	//方式2: 定义并完成初始化
	var s2 = []int{1,2,3}
	fmt.Println(s2)

	//方式3,使用make函数
	//make([]T, length, capacity) 类型、长度、容量。其中容量capacity为可选参数。
	s3 := make([]int,3)
	s3[0] = 1
	s3[1] = 2
	fmt.Println(s3) // [1 2 0]  []int类型未初始化的元素为0

	s4 := make([]string,3)
	s4[0] = "a"
	s4[1] = "b"
	fmt.Println(s4)  // [a b ]  []string类型 未初始化的元素为空
}
切片验证

验证结果:

  • 切片本身为指针,用来指向数组
  • 切片间可共享数组(相同容量间)
  • 切片扩容时,会重新开辟数组空间,并完成值copy
import "fmt"

func main(){
	a1 := [3]int{1,2,3}
	fmt.Println("数组内容:",a1)
	fmt.Println("首元素地址:",&a1[0])  //0xc00000c340
	fmt.Printf("a1地址:%p\n",&a1)  //0xc00000c340 说明输出为数组起始地址,即第一个元素地址
	fmt.Println("-------------")

	s1 := a1[0:1]
	fmt.Println(&s1[0])   //0xc00000c340  s1[0]与a[0]地址相同,说明切片本身是一个指针。指向数组
	fmt.Println("切片容量:",cap(s1))
	fmt.Println("切片内容:",s1)
	fmt.Println("-------------")

	s2 := append(s1,4)
	fmt.Println(&s2[0])     //0xc00000c340  s2[0]与s1[0]相同,说明切片间共享数组
	fmt.Println("切片容量:",cap(s2))
	fmt.Println("切片内容:",s2)
	fmt.Println("-------------")


	s3 := append(s2,5,6,7)
	fmt.Println(&s3[0])     //0xc00000a3f0  s3[0]与s2[0]不同,切片扩容后,重新开辟空间
	fmt.Println("切片容量:",cap(s3))
	fmt.Println("切片内容:",s3)

	/*
	通过切片s2修改s2[0], 发现s1[0]、a1[0]、s2[0] 均发生改变。进一步说明扩容前数组共享
	而s3[0]未被修改,说明扩容后的切片会重新开辟数组空间,并copy数组值,
	*/
	s2[0] = 10
	fmt.Println(a1[0])  //10
	fmt.Println(s1[0])  //10
	fmt.Println(s2[0])  //10
	fmt.Println(s3[0])  //1
}

指针

指针:存储某个变量起始内存地址 的变量

声明指针

声明格式:var 指针变量名 *指针类型

  • 操作符 “&” 取变量地址, “*” 通过指针访问目标对象
  • 指针不能运算
  • 当一个指针被定义后没有分配到任何变量量时,它的值为 nil。 nil 指针也称为空指针
import "fmt"
func main(){
	a := 10
	fmt.Printf("a的地址为%p\n",&a) //0xc0000160b0

	var p1 *int
	if p1 == nil {  //判断p1是否为nil。
		fmt.Println("p1为nil 。。。")
		p1 = &a
	}

	fmt.Println(p1)  // 0xc0000160b0 输出为a的内存地址
	fmt.Printf("p的地址为%p\n",&p1)  //0xc000006030 自身所占内存地址
	fmt.Println(*p1) //10  内存地址中所指向的值
	
	*p1 = 20  //使用指针修改所指向变量的值
	fmt.Println("a的值为:",a)  //20
}
指针数组

指针数组:元素为指针类型的数组
eg: var p [3]*string

import "fmt"

func main(){
	fmt.Println("指针数组测试。。。")
	//定义三个int变量
	a := 10
	b := 20
	c := 30
	fmt.Println(&a)  //0xc0000160c0
	fmt.Println(&b)  //0xc0000160c8
	fmt.Println(&c)  //0xc0000160d0

	//定义指针类型的数组
	var p1 [3]*int
	
	//将变量地址存入数组中
	p1[0] = &a
	p1[1] = &b
	p1[2] = &c

	//输出指针数组
	fmt.Println(p1) //[0xc0000160c0 0xc0000160c8 0xc0000160d0]
}
数组指针

数组指针:指向数组类型的指针

import "fmt"

func main(){
	fmt.Println("数组指针测试。。。")
	a, b, c := 10, 20, 30

	//定义数组
	var arr [3]int
	arr[0] = a
	arr[1] = b
	arr[2] = c
	fmt.Println("数组:",&arr)  //数组:&[10 20 30]  数组地址为其中元素的地址范围,数组本身没有确定地址。

	//定义数组指针
	var p1 *[3]int

	//指针指向数组
	p1 = &arr
	fmt.Println("p1指针指向:",p1)  //输出指向  &[10 20 30]
	fmt.Println("p1指针指向:",*p1)  //输出指向内容  [10 20 30]

	//使用指针修改数组值
	p1[0] = 100
	fmt.Println("数组:",arr)  // [100 20 30]  数组中值被修改
	fmt.Println("a的值:",a)  //a的值没有变化,因为,数组中存储的是a变量的值拷贝。而不是a本身
}

map

map:是Go中的内置类型。是一种无序的键值对集合

声明map

声明语法:
1)var 变量量名 map[key类型]value类型
2)变量量名 := make(map[key类型]value类型)

import "fmt"

func main(){
	//方式1:使用var定义
	var stu = map[int]string{}
	stu[01] = "zhangsan"
	stu[02] = "lisi"
	stu[03] = "wangwu"
	fmt.Println(stu)

	//方式2:使用make函数
	var stu2 = make(map[int]string)
	stu2[01] = "二狗"
	stu2[02] = "三猪"
	stu2[03] = "四鸭"
	fmt.Println(stu2)

	//方式3:自动推导类型
	stu3  := map[int]string{
		01:"哈哈哈",
		02:"嘿嘿嘿",
		03:"呵呵呵",
	}
	fmt.Println(stu3)
}

使用细节

  • map是无序的,每次打印出来的map都会不⼀样,它不能通过index获取,而必须通过key获取。
  • map的长度是不固定的,可扩展。内置len(),但无法使用cap()
  • 同⼀个map中key必须保证唯一。
  • key的数据类型必须是可参与比较运算的 类型,也就是支持==或!=操作的类型。如布尔型、整数型、浮点型、字符串串 型、数组。对于切片、函数等引用类型则不能作为键的类型。
  • 和slice⼀一样,map也是⼀种引用类型
操作map

查看元素是否存在:value, ok := map[key]
删除:delete(map, key)

清空map

  • Go语言没有为map提供任何清空所有元素的函数;
  • 清空map的唯一办法是重新make一个新的map;
  • 不用担心垃圾回收的效率,Go语⾔言的垃圾回收比写一个清空函数更高效
//操作map demo
import "fmt"

func main(){
	//定义map
	stu3 := map[int]string{
		01:"哈哈哈",
		02:"嘿嘿嘿",
		03:"呵呵呵",
		04:"哼哼哼",
	}
	fmt.Println(stu3)

	//判断key=04的键值对是否存在,存在则删除
	v , ok := stu3[04]
	if ok {
		println("将要删除:",v)
		delete(stu3,04)  //删除
	}

	//遍历
	for k, v := range stu3{
		fmt.Println(k,v)
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值