引用
一、数组
var a [3]int // 定义长度为3的int型数组, 元素全部为0
var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2, 3
var c = [...]int{2: 3, 1: 2} // 定义长度为3的int型数组, 元素为 0, 2, 3
var d = [...]int{1, 2, 4: 5, 6} // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6
var e = [...]int{5, 4: 1, 0, 2: 3, 2, 1: 4} // 定义长度为6的int型数组, 元素为 5, 4, 3, 2, 1, 0
Go数组初始化中的 [index:value] 代表的是在索引index处的位置上值为value, 如果索引值越界了就会重置。
数组是值传递。
二、切片
var (
a []int // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
b = []int{} // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
c = []int{1, 2, 3} // 有3个元素的切片, len和cap都为3
d = c[:2] // 有2个元素的切片, len为2, cap为3
e = c[0:2:cap(c)] // 有2个元素的切片, len为2, cap为3
f = c[:0] // 有0个元素的切片, len为0, cap为3
g = make([]int, 3) // 有3个元素的切片, len和cap都为3
h = make([]int, 2, 3) // 有2个元素的切片, len为2, cap为3
i = make([]int, 0, 3) // 有0个元素的切片, len为0, cap为3
)
slice[i:j]
slice[i:j:k]
// 其中 i 表示从 slice 的第几个元素开始切,j 控制切片的长度(j-i),k 控制切片的容量(k-i),如果没有给定 k,则表示切到底层数组的最尾部。
切片是引用传递。
三、迭代
// 索引迭代
for i := range a {
}
// 索引和值迭代
for i,v := rang a {
}
// 值迭代
for _,v := rang a {
}
// 根据长度迭代
for i := 0; i < len(a); i++ {
}
四、底层实现
// reflect/value.go
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
type sliceHeader struct {
Data unsafe.Pointer
Len int
Cap int
}
nil 切片和空切片是不一样的,
var slice []int // nil切片 Data是nil
// 空切片 Data有指向内存地址
silce := make( []int , 0 )
slice := []int{ }
四、转换
// 数组转字符串
func BytesToString(b []byte) string {
bh := (*reflect.SliceHeader)(unsafe.Pointer(&b))
sh := reflect.StringHeader{bh.Data, bh.Len}
return *(*string)(unsafe.Pointer(&sh))
}
// 字符串转字节
func StringToBytes(s string) []byte {
sh := (*reflect.StringHeader)(unsafe.Pointer(&s))
bh := reflect.SliceHeader{sh.Data, sh.Len, 0}
return *(*[]byte)(unsafe.Pointer(&bh))
}
网友评论