Go常用集合

数组和切片

数组

  • 容量不可伸缩
  • 两个数组可以比较

声明:

	var a [3]int // 声明并初始化为默认零值
	a[0] = 1
	b := [3]int{1, 2, 3}           // 声明同时初始化
	c := [2][2]int{{1, 2}, {3, 4}} // 多维数组初始化
	t.Log(a[0], a[2])
	t.Log(b[2])
	t.Log(c[1][1])

遍历:

	arr := [...]int{1, 2, 3, 4, 5, 6} // 自动判断长度

	for i := 0; i < len(arr); i++ { // 典型写法遍历数组
		t.Log(arr[i])
	}

	for idx, e := range arr { // 相当于其它语言的foreach
		t.Log(idx, e)
	}

	for _, e := range arr { // 我们可能用不到 idx 但go语言定义一个值不去使用编译会不通过 使用_代表不关心这个结果,来占位
		t.Log(e)
	}

截取:

a[开始索引(包含):结束索引(不包含)]

	arr := [...]int{1, 2, 3, 4, 5, 6}
	// a[开始索引(包含):结束索引(不包含)]
	t.Log(arr[0:1]) // 1
	t.Log(arr[2:]) // 3 4 5 6
	t.Log(arr[1:len(arr)]) // 2 3 4 5 6
	t.Log(arr[1:3]) // 2 3

切片

  • 容量可以伸缩
  • 两个切片不能比较

内部结构:

slice

声明:

	var s0 []int            // 定义看起来特别像数组,但没有指定长度
	t.Log(len(s0), cap(s0)) // 0 0
	s0 = append(s0, 1)
	t.Log(len(s0), cap(s0)) // 1 1

	s1 := []int{1, 2, 3, 4} // 初始化一个切片
	t.Log(len(s1), cap(s1)) // 4 4

	// []type,len,cap 其中len个元素会被初始化为默认零值,未初始化元素不可以访问
	s2 := make([]int, 3, 5)    // len为3 cap为5
	t.Log(len(s2), cap(s2))    // 3 5
	t.Log(s2[0], s2[1], s2[2]) // 成功被初始化 结果:0 0 0
	//t.Log(s2[0], s2[1], s2[2], s2[3]) // 出现了一个错误 index out of range [3]
	s2 = append(s2, 1)
	t.Log(s2[0], s2[1], s2[2], s2[3]) // 0 0 0 1
	t.Log(len(s2), cap(s2))           // 4 5 len变成了4

共享存储结构:

slice

	s := []int{}
	for i := 0; i < 10; i++ {
		s = append(s, i) // 为什么重新赋值给s,是因为结构体指向的连续存储空间进行了变化,并把原有的连续存储空间拷贝到新的连续存储空间
		t.Log(len(s), cap(s))
	}
	/** 运行结果:当len不够用的时候会增长,cap不够用的时候增长为前一个cap的2倍
		TestSliceGrowing: slice_test.go:28: 1 1
	    TestSliceGrowing: slice_test.go:28: 2 2
	    TestSliceGrowing: slice_test.go:28: 3 4
	    TestSliceGrowing: slice_test.go:28: 4 4
	    TestSliceGrowing: slice_test.go:28: 5 8
	    TestSliceGrowing: slice_test.go:28: 6 8
	    TestSliceGrowing: slice_test.go:28: 7 8
	    TestSliceGrowing: slice_test.go:28: 8 8
	    TestSliceGrowing: slice_test.go:28: 9 16
	    TestSliceGrowing: slice_test.go:28: 10 16
	*/

Map声明、元素访问及遍历

声明:

	m1 := map[int]int{1: 1, 2: 4, 3: 9} // 初始化一个map
	t.Log(m1[2])                        // 4
	t.Logf("len m1 = %d", len(m1))      // len m1 = 3
	m2 := map[int]int{}                 // 初始化一个空map
	m2[4] = 16                          // 赋值
	t.Logf("len m2 = %d", len(m2))      // len m2 = 1
	m3 := make(map[int]int, 10)         // 使用make初始化map
	t.Logf("len m3 = %d", len(m3))      // len m3 = 0 填的len为10,但打印出来为0

元素访问:

	// key在map中存在吗?
	// key存在但是对应的值是空值
	m1 := map[int]int{}
	t.Log(m1[1]) // 0 不存在输出0
	m1[2] = 0    // 设置value正好为0
	t.Log(m1[2]) // 0 也是0 该如何判断key是否存在呢
	// 需要主动去判断
	if v, ok := m1[3]; ok {
		t.Logf("key 3's value is %d", v)
	} else {
		t.Log("key 3 is not existing.") // 将输出这句话
	}

	m1[3] = 9
	if v, ok := m1[3]; ok {
		t.Logf("key 3's value is %d", v) // 将输出这句话
	} else {
		t.Log("key 3 is not existing.")
	}

遍历:

	m1 := map[int]int{1: 1, 2: 4, 3: 9}
	for k, v := range m1 {
		t.Log(k, v)
	}
	/** 运行结果
	    TestTravelMap: map_test.go:41: 1 1
	    TestTravelMap: map_test.go:41: 2 4
	    TestTravelMap: map_test.go:41: 3 9
	 */

Map与工厂模式,实现Set

  • Map的value可以是一个方法
  • 与Go的Dock type接口方式一起,可以方便的实现单一方法对象的工厂模式
	m := map[int]func(op int) int{}
	m[1] = func(op int) int {
		return op
	}
	m[2] = func(op int) int {
		return op * op
	}
	m[3] = func(op int) int {
		return op * op * op
	}
	t.Log(m[1](2), m[2](2), m[3](2)) // 运行结果 2 4 8

实现Set:

Go内置集合中没有Set实现,可以map[type]bool

  • 元素的唯一性
  • 基本操作
    • 添加元素
    • 判断元素是否存在
    • 删除元素
    • 元素个数
	mySet := map[int]bool{}
	mySet[1] = true // 添加元素 value置为true
	n := 1
	if mySet[n] {
		t.Logf("%d is existing.", n) // 输出这句话
	} else {
		t.Logf("%d is not existing.", n)
	}

	delete(mySet, 1) // 把1这个key从map中删除
	
	if mySet[n] {
		t.Logf("%d is existing.", n)
	} else {
		t.Logf("%d is not existing.", n) // 输出这句话
	}
展开阅读全文
©️2020 CSDN 皮肤主题: 技术黑板 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值