funcmain(){var array []int
array =Append(array)
fmt.Println(array)// []}funcAppend(s []int){
s =append(s,1)}
正确
funcmain(){var array []int
array =Append(array)
fmt.Println(array)// [1]}funcAppend(s []int)[]int{
s =append(s,1)return s
}
例子:
funcAppend(s[]int){//s[0] = 1024 //① 位置1
s =append(s,100)
s =append(s,200)//s[0] = 1024 //② 位置2// fmt.Println(s) }funcmain(){var s []intfor i:=0; i<3; i++{
s =append(s,i)}Append(s)
fmt.Println(s)}
① 位置1: 我们在main函数中的输出结果是 [1024 1 2] 我们的append是值拷贝,是不会进行修改原切片
② 位置2: main函数中输出结果:[0 1 2] 因为这里其实发生了扩容,那么已经是扩容了,那么扩容部分就是另一块内存了。所以就没有修改成功。
2.3 命名区别
1.var a []int// 定义一个 []int 类型的变量 a , 并分配内存空间给 a 赋 []int 的 nil。2. a :=[]int{}// 定义一个 []int 类型的变量 a , 并分配内存空间给 a , 但是不为nil。3. a :=make([]int,3)// 分配内存函数,仅用于 chan、map 和 slice,返回的数据类型就是这三个类型本身// chan、map 和 slice 这三种类型本身就是引用类型,所以没必要返回指针类型4. a :=new(int)// 声明一个 int 型指针 a,分配一个 int 的内存空间,并把内存地址给 a。
3. map
推荐这篇博文 Map底层实现
3.1 底层结构
type hmap struct{// Note: the format of the hmap is also encoded in cmd/compile/internal/gc/reflect.go.// Make sure this stays in sync with the compiler's definition.
count int// 键值对的数量
flags uint8// 状态标识,比如正在被写、buckets和oldbuckets在被遍历、等量扩容(Map扩容相关字段)
B uint8// 2^B=len(buckets)
noverflow uint16// 溢出桶里bmap大致的数量
hash0 uint32// hash 因子
buckets unsafe.Pointer
// 指向一个数组(连续内存空间),数组的类型为[]bmap,这个字段我们可以称之为正常桶
oldbuckets unsafe.Pointer
// 扩容时,存放之前的buckets(Map扩容相关字段)
nevacuate uintptr// 分流次数,成倍扩容分流操作计数的字段(Map扩容相关字段)
extra *mapextra
// 溢出桶结构,正常桶里面某个bmap存满了,会使用这里面的内存空间存放键值对}
3.2 赋值
var mp1 map[int][int]// 1
mp1[1]=1
mp2 :=map[int][int]{}// 2
mp2[1]=1