How to use slice in golang
Editor to share with you how to use slice in golang, I believe most people do not know much about it, so share this article for your reference, I hope you can learn a lot after reading this article, let's go to know it!
Slice structure definition
Type slice struct {
Array unsafe.Pointer
Len int
Cap int
}
Create slice
/ / maxSliceCap returns the maximum capacity for a slice.
Func maxSliceCap (elemsize uintptr) uintptr {
If elemsize
< uintptr(len(maxElems)) { return maxElems[elemsize] } return _MaxMem / elemsize } func makeslice(et *_type, len, cap int) slice { // NOTE: The len >MaxElements check here is not strictly necessary
/ / but it produces a 'len out of range' error instead of a' cap out of range' error
/ / when someone does make ([] T, bignumber). 'cap out of range' is true too
/ / but since the cap is only being supplied implicitly, saying len is clearer.
/ / See issue 4085.
/ / calculate the maximum distributable length
MaxElements: = maxSliceCap (et.size)
If len
< 0 || uintptr(len) >MaxElements {
Panic (errorString ("makeslice: len out of range"))
}
If cap
< len || uintptr(cap) >MaxElements {
Panic (errorString ("makeslice: cap out of range"))
}
/ / assign continuous interval
P: = mallocgc (et.size*uintptr (cap), et, true)
Return slice {p, len, cap}
}
Slice capacity expansion
/ / cap target capacity
Func growslice (et * _ type, old slice, cap int) slice {
If et.size = = 0 {
If cap
< old.cap { panic(errorString("growslice: cap out of range")) } // append should not create a slice with nil pointer but non-zero len. // We assume that append doesn't need to preserve old.array in this case. return slice{unsafe.Pointer(&zerobase), old.len, cap} } newcap := old.cap doublecap := newcap + newcap if cap >Doublecap {
Newcap = cap
} else {
/ / less than 1024 and expand the capacity
If old.len
< 1024 { newcap = doublecap } else { // 大于1024,*1.25 for newcap < cap { newcap += newcap / 4 } } } var lenmem, newlenmem, capmem uintptr const ptrSize = unsafe.Sizeof((*byte)(nil)) switch et.size { case 1: lenmem = uintptr(old.len) newlenmem = uintptr(cap) capmem = roundupsize(uintptr(newcap)) newcap = int(capmem) case ptrSize: lenmem = uintptr(old.len) * ptrSize newlenmem = uintptr(cap) * ptrSize capmem = roundupsize(uintptr(newcap) * ptrSize) newcap = int(capmem / ptrSize) default: lenmem = uintptr(old.len) * et.size newlenmem = uintptr(cap) * et.size capmem = roundupsize(uintptr(newcap) * et.size) newcap = int(capmem / et.size) } if cap < old.cap || uintptr(newcap) >MaxSliceCap (et.size) {
Panic (errorString ("growslice: cap out of range"))
}
Var p unsafe.Pointer
If et.kind&kindNoPointers! = 0 {
P = mallocgc (capmem, nil, false)
Memmove (p, old.array, lenmem)
/ / The append () that calls growslice is going to overwrite from old.len to cap (which will be the new length)
/ / Only clear the part that will not be overwritten.
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 {
Memmove (p, old.array, lenmem)
} else {
For I: = uintptr (0); I < lenmem; I + = et.size {
Typedmemmove (et, add (p, I), add (old.array, I))
}
}
}
/ / New slice
Return slice {p, old.len, newcap}
}
The above is all the contents of the article "how to use slice in golang". Thank you for reading! I believe we all have a certain understanding, hope to share the content to help you, if you want to learn more knowledge, welcome to follow the industry information channel!