// 判断是否会溢出 if overflow || capmem > maxAlloc { panic(errorString("growslice: cap out of range")) }
// 内存分配
var p unsafe.Pointer if et.kind&kindNoPointers != 0 { p = mallocgc(capmem, nil, false) // 清空不需要数据拷贝的部分内存 memclrNoHeapPointers(add(p, newlenmem), capmem-newlenmem) } else { // Note: can't use rawmem (which avoids zeroing of memory), because then GC can scan uninitialized memory. p = mallocgc(capmem, et, true) if writeBarrier.enabled { // gc 相关 // Only shade the pointers in old.array since we know the destination slice p // only contains nil pointers because it has been cleared during alloc. bulkBarrierPreWriteSrcOnly(uintptr(p), uintptr(old.array), lenmem) } }
// 数据拷贝 memmove(p, old.array, lenmem)
return slice{p, old.len, newcap} }
切片拷贝 (copy)
切片的浅拷贝
1 2 3 4 5 6 7
shallowCopy := data[:1]
ptr1 := unsafe.Pointer(&shallowCopy)
opt1 := (*[3]int)(ptr1)
fmt.Println(opt1[0])
下面是上述代码的汇编代码:
上面,先将 data 的成员数据拷贝到寄存器,然后从寄存器拷贝到shallowCopy的对象中。(注意到只是拷贝了指针而已, 所以是浅拷贝)
funcslicecopy(to, fm slice, width uintptr)int { if fm.len == 0 || to.len == 0 { return0 }
n := fm.len if to.len < n { n = to.len }
// 元素大小为0,则直接返回 if width == 0 { return n }
// 竟态分析和内存扫描 // ...
size := uintptr(n) * width // 直接内存拷贝 if size == 1 { // common case worth about 2x to do here *(*byte)(to.array) = *(*byte)(fm.array) // known to be a byte pointer } else { memmove(to.array, fm.array, size) } return n }