每天5分钟-玩转golang,第2节 数据类型

302 阅读4分钟

1. 数组(array)

  • 定义: 数组是具有相同数据类型的数据项组成的一组长度固定的序列
  • 声明: 数组声明需要指定组成元素的类型以及存储元素的数量(长度),在数组声明后,其长度不可修改
    • [length]type{item1, item2} //指定数量
    • [...]type{item1, item2} //任意数量
    • [length]type{index1:item1, index3:item3} //指定位置 初始化数组
func arraycase2(){
	// 数组任意数量
	bounds := [...]int{1,2,3,4,5}
	fmt.Println(bounds)
	fmt.Println(len(bounds))

	// 指定下标 初始化数组
	nums := [...]string{1:"php", 2:"java", 5:"python"}
	fmt.Println(nums)
	fmt.Println(len(nums))

	// 修改数组中的元素
	nums[0] = "c++"
	nums[1] = "golang"
	fmt.Println(nums)
	fmt.Println(len(nums))

	// 遍历数组中的元素
	for index, value := range nums {
		fmt.Println(index, value)
	}

}

多维数组

func arraycase3(){
	// 定义3行2列的数组
	student01 := [3][2]string{ {"a", "b"}, {"c"}, {"d"}   }
	fmt.Println(student01)
}

2.切片(slice)

  • 定义: 切片是长度可变的数组 具有相同类型的的数据 组成的长度可变的序列
  • 组成部分:
    • 指针 指向 切片第一个元素只想的数组元素的地址
    • 长度 切片元素的数量
    • 容量 切片开始 到 结束位置 元素的总数量
  • 声明 需要指定元素的类型 但不需要指定长度 var names []string
  • 初始化
    • []type{v1, v2, ..., vn}
    • make([]type, len, cap) //长度为len,容量为cap的切片 len要小于cap
    • slice[start:end:cap] //定义切片的容量 end <= cap <= src_cap
  • 操作切片
    • 如果切片是基于数组创建的 数组的底层元素进行改变 切片的数据也会跟着改变
    • 如果切片是基于数组创建的 切片的底层数据进行改变 数组的数据也会跟着改变
    • 如果切片2是基于切片1创建的 切片1 切片2互相独立 互补影响
  • append操作, slice = append(slice, item)
  • copy操作
    • copy(slice1, slice2) // slice1切片 复制 slice2切片, 复制的数量为两者的最小值

初始化切片

func slicecase1(){
	fmt.Println("\nslicecase1")
	slice_score01 := []int{1,3,1,2}
	slice_score02 := []int{}
	slice_score03 := make([]int, 3, 5)
	slice_score04 := make([]string, 1, 3)

	fmt.Println(slice_score01, len(slice_score01), cap(slice_score01))
	fmt.Println(slice_score02, len(slice_score02), cap(slice_score02))
	fmt.Println(slice_score03, len(slice_score03), cap(slice_score03))
	fmt.Println(slice_score04, len(slice_score04), cap(slice_score04))
}

output:
slicecase1
[1 3 1 2] 4 4
[] 0 0
[0 0 0] 3 5
[] 1 3

操作切片

func slicecase2(){
	fmt.Println("\nslicecase2")
	array_score := [...]int{1,1,3,1,4,1,4}
	slice_score01 := array_score[1:4]
	fmt.Println("\nold")
	fmt.Println(array_score, len(array_score), cap(array_score))
	fmt.Println(slice_score01, len(slice_score01), cap(slice_score01))

	// 修改数组底层元素, 切片共享底层数组,若某个切片元素发生变化,则数组和其他有共享元素的切片也会发
	fmt.Println("\narray change")
	array_score[1] = 11111
	fmt.Println(array_score, len(array_score), cap(array_score))
	fmt.Println(slice_score01, len(slice_score01), cap(slice_score01))

	// 修改切片底层元素
	fmt.Println("\nslice change")
	slice_score01[0] = 2222
	fmt.Println(array_score, len(array_score), cap(array_score))
	fmt.Println(slice_score01, len(slice_score01), cap(slice_score01))
}



output:
slicecase2

old
[1 1 3 1 4 1 4] 7 7
[1 3 1] 3 6

array change
[1 11111 3 1 4 1 4] 7 7
[11111 3 1] 3 6

slice change
[1 2222 3 1 4 1 4] 7 7
[2222 3 1] 3 6

切片append操作

func slicecase_append(){
   fmt.Println("\nslicecase_append")
   nums1 := []int{1,2,3,4,5} //初始化一个切片
   nums2 := nums1[:] //新建切片
   fmt.Printf("nums1: %v, %d, %d\n", nums1, len(nums1), cap(nums1))
   fmt.Printf("nums2: %v, %d, %d\n", nums2, len(nums2), cap(nums2))

   nums2 = append(nums2, 100) //num2添加一个元素
   // 使用 append 对切片增加一个或多个元素并返回修改后切片,当长度在容量范围内时 只增加长度,容量和底层数组不变。
   // 当长度超过容量范围则会创建一个新的底层数组, 并对容量进行智能运算(元素数量<1024 时,约按原容量 1 倍增加,>1024 时约按原容量 0.25 倍增加)
   fmt.Println("\nappend nums2")
   fmt.Printf("nums1: %v, %d, %d\n", nums1, len(nums1), cap(nums1))
   fmt.Printf("nums2: %v, %d, %d\n", nums2, len(nums2), cap(nums2))

   nums2[0] = 111111 //修改切片2元素
   fmt.Println("\nchange nums2")
   fmt.Printf("nums1: %v, %d, %d\n", nums1, len(nums1), cap(nums1))
   fmt.Printf("nums2: %v, %d, %d\n", nums2, len(nums2), cap(nums2))

   nums1[0] = 22222 //修改切片1元素
   fmt.Println("\nchange nums1")
   fmt.Printf("nums1: %v, %d, %d\n", nums1, len(nums1), cap(nums1))
   fmt.Printf("nums2: %v, %d, %d\n", nums2, len(nums2), cap(nums2))

   nums1 = append(nums1, 1,2,3,4,1,4) //num1添加多个元素
   fmt.Println("\nappend nums1")
   fmt.Printf("nums1: %v, %d, %d\n", nums1, len(nums1), cap(nums1))
   fmt.Printf("nums2: %v, %d, %d\n", nums2, len(nums2), cap(nums2))

}

output:
slicecase_append
nums1: [1 2 3 4 5], 5, 5
nums2: [1 2 3 4 5], 5, 5

append nums2
nums1: [1 2 3 4 5], 5, 5
nums2: [1 2 3 4 5 100], 6, 10

change nums2
nums1: [1 2 3 4 5], 5, 5
nums2: [111111 2 3 4 5 100], 6, 10

change nums1
nums1: [22222 2 3 4 5], 5, 5
nums2: [111111 2 3 4 5 100], 6, 10

append nums1
nums1: [22222 2 3 4 5 1 2 3 4 1 4], 11, 12
nums2: [111111 2 3 4 5 100], 6, 10
[root@happy go]# 

切片copy操作

func slice_copy(){
	fmt.Println("\n slice_copy:")
	user01 := []string{"switch", "net", ""}
	user02 := []string{"a", "b", "c", "d"}
	user03 := []string{"1", "2", "3", "4", "5"}
	fmt.Printf("%q, %q, %q\n", user01, user02, user03)

	copy(user01, user02)  // user01切片 复制 user01切片, 复制的数量为两者的最小值
	fmt.Printf("copy(user01, user02), %q, %q, %q\n", user01, user02, user03)

	copy(user03, user02)  // user03切片 复制 user01切片, 复制的数量为两者的最小值
	fmt.Printf("copy(user03, user02), %q, %q, %q\n", user01, user02, user03)
}


output:
 slice_copy:
["switch" "net" ""], ["a" "b" "c" "d"], ["1" "2" "3" "4" "5"]
copy(user01, user02), ["a" "b" "c"], ["a" "b" "c" "d"], ["1" "2" "3" "4" "5"]
copy(user03, user02), ["a" "b" "c"], ["a" "b" "c" "d"], ["a" "b" "c" "d" "5"]

3. 映射 map

  • 定义: 映射存储一系列无序的 key value对
  • 声明: 需要指定组成元素 key 和 value 的类型
    • map[keyt_ype]value_type{k1:v1, k2:v2, ..., kn:vn}
    • map[ktype]vtype{ } //创建空map
    • make(map[ktype]vtype) //通过 make 函数创建映射
  • 操作
    • len 查看元素的数量
    • delte 删除map的指定key
    • range 遍历map 返回key和value

func mapcase(){
	config_kb := map[string]string{"ecs": "houyi", "slb": "lvs", "oss": "chiji", "tianji": "ops1"}

	// 使用 len 函数获取映射元素的数量
	fmt.Println(config_kb, len(config_kb))

	fmt.Println(config_kb["pangu"]) // 数据不存在的话 返回空值
	fmt.Println(config_kb["ecs"])

	// 判断key是否存在, 通过 key 访问元素时可接收两个值,第一个值为 value,第二个值为 bool 类型表示元 素是否存在,若存在为 true,否则为 false
	values, satus := config_kb["pangu"]
	fmt.Println("config_kb[\"pangu\"]", values, satus)

	values1, satus1 := config_kb["ecs"]
	fmt.Println("config_kb[\"ecs\"]", values1, satus1 )

	// 修改数据 存在key就修改 不存在就新增
	config_kb["pangu"] = "xxx"
	fmt.Println(config_kb)

	// delete 删除已经存在的key 存在就删除
	delete(config_kb, "vpc")
	fmt.Println("delete vpc",config_kb)

	delete(config_kb, "ecs")
	fmt.Println("delete ecs",config_kb)

	// 遍历map range 返回两个元素分别为映射的 key 和 value
	for key, value := range config_kb{
		fmt.Println(key, value)
	}

练习 统计各个单词出现的次数

func static_words(){
	//统计各个单词出现的次数
	raw_string := "https://github.com/avelino/awesome-go?utm_source=gold_browser_extension"
	config_word := map[string]int{} // 初始化一个map记录各个单词出现的次数

	for _, word := range raw_string{
		_, status := config_word[string(word)]
		if status{
			config_word[string(word)]++
		}else{
			config_word[string(word)] = 0
		}
	}

	fmt.Printf("%v\n", config_word)
}