This is a creation in Article, where the information may have evolved or changed.
Original
- Slices are always going to have an account to see this code
Package Mainimport ("FMT" "unsafe") type Slice struct {ptr unsafe. Pointer//Array Pointer len Int//Slice length cap int//slice capacity}//Because a pointer calculation is required, you need to get I The length of the NT//32-bit int length = 4//64-bit int length = 8var Intlen = Int (unsafe. Sizeof (int (0))) Func main () {s: = make ([]int, 10, 20)//use pointer to read slice memory data if Intlen = = 4 {//32 bit M : = * (*[4 + 4*2]byte) (unsafe.) Pointer (&s)) fmt. PRINTLN ("Slice Memory:", M)} else {//64-bit m: = * (*[8 + 8*2]byte) (unsafe. Pointer (&s)) fmt. PRINTLN ("Slice Memory:", M)}//convert slice to custom slice struct slice: = (*slice) (unsafe. Pointer (&s)) fmt. Println ("Slice struct:", slice) fmt. Printf ("Ptr:%v len:%v cap:%v \ n", Slice.ptr, Slice.len, Slice.cap) fmt. Printf ("Golang slice len:%v cap:%v \ n", Len (s), Cap (s)) s[0] = 0 S[1] = 1 S[2] = 2//turn to array output arr: = * (*[3]i NT) (unsafe. Pointer (slice.ptr)) fmt. PRINTLN ("Array values:", arr)//Modify slice LEn slice.len = fmt. Println ("Slice len:", Slice.len) fmt. Println ("Golang Slice len:", Len (s))}
- Do you see what's coming?
- Reserve Knowledge:
- Unsafe. Pointer similar to the void* in C language
- Unsafe. Pointer occupied space = number of bytes of type int
- Conclusion:
- The structure of the slice is equivalent to the slice structure.
// 每次cap改变,指向array的ptr就会变化一次s := make([]int, 1)fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))for i := 0; i < 5; i++ { s = append(s, i) fmt.Printf("len:%d cap: %d array ptr: %v \n", len(s), cap(s), *(*unsafe.Pointer)(unsafe.Pointer(&s)))}fmt.Println("Array:", s)
- Replace the main program above, what did you find?
- Each time the append, the address changes, indicating that when the cap is insufficient, a copy operation is generated.
- The actual go in append to enlarge the CAP is regular. In cases where the cap is less than 1024, it expands to 2 * caps each time, and expands to the 1.25 * cap each time it is greater than 1024. So the above test has a cap change of 1, 2, 4, 8