本文主要介绍 golang 内置数据类型的 array, slice, map。这几种数据类型在平常使用中是很是常见的。java
定义语法以下:
var arr [n]type
其中 arr 是数组变量的名称(标识符), [n]type 表示这个数组是类型为 type 且长度为 n 的数组(type 能够是任何基本类型,也能够是任何自定义类型)
//实例演示 var arr [10]int //定义一个长度为10的 int 类型的数组 arr[0] = 42 //array 数组下标是从0开始的,给数组第一个元素赋值42 arr[1] = 13//给数组第二个元素赋值13 //打印数组第一个元素 fmt.Printf("数组 arr 第一个元素是 %d\n", arr[0]) //打印数组最后一个元素,arr[9]由于没有初始化,输出 int 类型的零值 0 fmt.Printf("数组 arr 最后一个元素是 %d\n", arr[9])
定义数组的时候,能够把[n]type 看作一个完整的类型,举个例子,[3]int 和 [4]int 能够认为是不一样的数据类型,数组的长度也是不可修改的当把一个 array类型的数据做为函数参数传递的时候,传递的是 array 的copy(拷贝值)而不是引用python
/** * 数组是值传递而非引用传递 */ func test(arr [4]int) int { var sum int for i, v := range arr { sum = sum + v arr[i] = sum } //打印结果是[1 3 7 12] fmt.Printf("%+v\n", arr) return sum } func main() { arr := [4]int{1, 2, 4, 5} //打印结果 12 fmt.Printf("%d\n", test(arr)) //打印结果[1 2 4 5],把 arr 传递给 test函数,且函数内修改了数组,没有影响原数组,证实数组在函数参数中是传递 copy而不是引用 fmt.Printf("%v\n", arr) }
//快捷方式定义数组 arr := [3]int{1, 2, 3} //使用 ...替代长度让编译器自动计算数组的长度 arr1 := [...]int{3, 5, 5} //二维数组 darr :=[2][3]int{[3]int{1,2,3}, [3]int{33,33,33}} darr1 := [2][3]int{{2, 3, 4}, {1, 3, 4}}
数组在一开始的时候,就要知道它的长度,然而不少时候咱们并不能肯定数组的大小,须要一种 "动态数组".在 golang 中 slice 为咱们提供了这种可能。golang
slice 的定义和 array 很是相近,区别就是不用设置 n
语法 var slice[]int说明:以上语法定义了一个 int 类型的 slice,数组
//实例说明 //定义一个byte 类型的 slice,注意 byte 是uint8的别名,byte类型的 slice中,若是元素赋值为汉字超出 uint8的范围就会报错 slice := []byte{'a', 'b', 'c'}
slice 能够从已经存在的数组(array)或者切片(slice)从新定义一个切片,语法格式为[i:j], i 是开始的索引,j 是结束的索引,可是最终的 slice 不包含 j 这个元素
//实例演示 var ar = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} var a, b []byte //变量a 实际上的内容为 c,d,e 且 a 和 ar 共用底层数据 a = ar[2:5] //变量 b 实际上的内容为 d,e 且 b 和 ar 共用底层数据 b = ar[3:5] //思考以下结果是什么? ar[4] = 'x' fmt.Printf("%c\n", ar[4])//显然是 x fmt.Printf("%c\n", a[2])//a[2]实际上指向的是 ar[4],结果是 x fmt.Printf("%c\n", b[1])//b[1]实际上指向的是 ar[4],结果是 x
ar[:n] 等价于 ar[0:n]
ar[n:] 等价于 ar[n:len(ar)]
ar[:] 等价于 ar[0:len(ar)]
//实例演示 var arr = [10]byte{'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j'} var aSlice, bSlie []byte aSlice = arr[:3] // a b c aSlice = arr[5:] //f g h i j aSlice = arr[:] // a b c d e f g h i j aSlice = arr[3:7] // d e f g, 长度 len=4, 容量 cap=10-3 bSlice = aSlice[1:3] // e f
slice 是引用类型,所以任何改变都会影响指向同一个 slice的其余 slice 或 数组。数据结构
slice 相似于结构体,包涵了下面三个部分app
- 一个指针:指向 slice 的起始地址
- slice 的长度 int 类型
- slice 的容量 int 类型
有一些内置函数能够操做 slice函数
Map是一种键值对数据结构,相似python 中的字典。定义语法以下:ui
map[keyType]valueType
slice 中索引只能是 int
,在 map 中 key能够是 int
string
等任何你想要的类型指针
实例演示以下code
//使用 string 类型的 key,int类型的 value,可使用 make 初始化 var numbers map[string]int //定义而且使用 make 初始化 numbers := make(map[string]int) //初始化后能够赋值 numbers["one"] = 1 numbers["two"] = 2 numbers["three"] = 3 //获取 map 某个 key 的 value fmt.Println(numbers["three"])
map 须要注意
- map是无序的,每次打印显示的结果可能都是不同的,只能使用 key 获取 value
- map 没有固定的长度,它是一种引用型变量
- len函数能够用于获取 map 的长度,返回 map 有多少个 key
- 经过 key改变 map 的 value 很是容易 只须要 使用相似
m["k"] = 1
的语法修改
//定义而且初始化 map rating := map[string]float32 {"C":5, "Go":4.5, "PHP":100} javaRating, ok := rating["Java"] if ok { //do something }else{ //do something } //删除 map 中的某个键值对 delete(rating, "C") m := make(map[string]string) m["hello"] = "world" m1 := m m1["hello"] = "girl" //m["hello"]的值也是 girl,由于底层指向数据一致
make 是 go 内置的一个方法,用于为 map,slice,channel 等内置类型分配内存,new能够为全部类型分配
new(T)给 T 分配零值内存,返回零值的内存地址,其实就是 *T,更详细的说,就是返回一个指针,指针指向的是 T 的零值
new 返回指针
make 主要用于 slice map channel,返回初始化后的 T。缘由在于 map slice channel底层的数据必须在初始化后才能指向他们。举个例子,slice 包涵了一个指针,这个指针实际指向的是另一个结构(包涵指针 长度 容量),在这些数据初始化以前 slice 是 nil,所以 slice,map,channel使用 make为他们底层的数据结构赋值合适的初始值
make 返回 非零值
个人博客即将同步至腾讯云+社区,邀请你们一同入驻:https://cloud.tencent.com/dev...