When you discover your mission, you will feel its demand. It will fill you with enthusiasm and a burning desire to get to work on it. — W. Clement Stone
funcmain() { slice1 := []int{1, 2, 3, 4} arrayPtr1 := (*int)(unsafe.Pointer(&slice1[0])) fmt.Printf("The address of the underlying array of slice1: %p\n", arrayPtr1)
slice2 := slice1 arrayPtr2 := (*int)(unsafe.Pointer(&slice2[0])) fmt.Printf("The address of the underlying array of slice2: %p\n", arrayPtr2)
slice3 := slice2[:] arrayPtr3 := (*int)(unsafe.Pointer(&slice3[0])) fmt.Printf("The address of the underlying array of slice3: %p\n", arrayPtr3)
slice4 := make([]int, len(slice3)) copy(slice4, slice3) arrayPtr4 := (*int)(unsafe.Pointer(&slice4[0])) fmt.Printf("The address of the underlying array of slice4: %p\n", arrayPtr4) }
// The address of the underlying array of slice1: 0xc00007a000 // The address of the underlying array of slice2: 0xc00007a000 // The address of the underlying array of slice3: 0xc00007a000 // The address of the underlying array of slice4: 0xc00007a020
... newcap := oldCap doublecap := newcap + newcap if newLen > doublecap { newcap = newLen } else { const threshold = 256 if oldCap < threshold { newcap = doublecap } else { // Check 0 < newcap to detect overflow // and prevent an infinite loop. for0 < newcap && newcap < newLen { // Transition from growing 2x for small slices // to growing 1.25x for large slices. This formula // gives a smooth-ish transition between the two. newcap += (newcap + 3*threshold) / 4 } // Set newcap to the requested cap when // the newcap calculation overflowed. if newcap <= 0 { newcap = newLen } } } ...
fmt.Printf("Pointer of nilSlice: %p\n", unsafe.Pointer(nilSliceHeader.Data)) fmt.Printf("Pointer of emptySlice: %p\n", unsafe.Pointer(emptySliceHeader.Data)) fmt.Printf("Pointer of emptySlice2: %p\n", unsafe.Pointer(emptySlice2Header.Data))
if emptySliceHeader.Data == emptySlice2Header.Data { fmt.Println("emptySlice and emptySlice2 point to the same zerobase address.") } else { fmt.Println("emptySlice and emptySlice2 do not point to the same zerobase address.") } }
// nilSlice: len=0, cap=0, is nil: true // emptySlice: len=0, cap=0, is nil: false // emptySlice2: len=0, cap=0, is nil: false // Pointer of nilSlice: 0x0 // Pointer of emptySlice: 0x58f360 // Pointer of emptySlice2: 0x58f360 // emptySlice and emptySlice2 point to the same zerobase address.
fmt.Println("Original slice before modifySlice:", originalSlice) arrayPtr := (*int)(unsafe.Pointer(&originalSlice[0])) fmt.Printf("The address of the underlying array before modifySlice: %p\n", arrayPtr)
modifySlice(originalSlice) fmt.Println("Original slice after modifySlice:", originalSlice) arrayPtr = (*int)(unsafe.Pointer(&originalSlice[0])) fmt.Printf("The address of the underlying array after modifySlice: %p\n", arrayPtr)
modifySlicePointer(&originalSlice) fmt.Println("Original slice after modifySlicePointer:", originalSlice) arrayPtr = (*int)(unsafe.Pointer(&originalSlice[0])) fmt.Printf("The address of the underlying array after modifySlicePointer: %p\n", arrayPtr) }
Original slice before modifySlice: [0 1 2] The address of the underlying array before modifySlice: 0xc000126000 Inside modifySlice (modified slice): [100 1 2 200] The address of the underlying array in modifySlice: 0xc000126000 Original slice after modifySlice: [100 1 2] The address of the underlying array after modifySlice: 0xc000126000 Inside modifySlicePointer (modified slice pointer): [100 1 2 200] The address of the underlying array in modifySlicePointer: 0xc000126000 Original slice after modifySlicePointer: [100 1 2 200] The address of the underlying array after modifySlicePointer: 0xc000126000
这里你可能只有一个疑问点,为什么 Original slice after modifySlice 的结果是 [100 1 2],而不是[100 1 2 200],这是因为其 len 为 3,所以只输出了三个数字。
如果originalSlice为:
1
originalSlice := []int{0, 1, 2}
结果为:
1 2 3 4 5 6 7 8 9 10
Original slice before modifySlice: [0 1 2] The address of the underlying array before modifySlice: 0xc0000ac000 Inside modifySlice (modified slice): [100 1 2 200] The address of the underlying array in modifySlice: 0xc0000b2030 Original slice after modifySlice: [100 1 2] The address of the underlying array after modifySlice: 0xc0000ac000 Inside modifySlicePointer (modified slice pointer): [100 1 2 200] The address of the underlying array in modifySlicePointer: 0xc0000b2060 Original slice after modifySlicePointer: [100 1 2 200] The address of the underlying array after modifySlicePointer: 0xc0000b2060
funcmain() { u := []user{ {"wesley", "medium"}, {"tfrain", "github"}, } n := make([]*user, 0, len(u)) for _, v := range u { fmt.Printf("%p\n", &v) n = append(n, &v) } fmt.Println(n) for _, v := range n { fmt.Println(v) } } // print before go 1.22 // 0xc000060020 // 0xc000060020 // [0xc000060020 0xc000060020] // &{tfrain github} // &{tfrain github}
// print after go 1.22 // 0xc000098020 // 0xc000098040 // [0xc000098020 0xc000098040] // &{wesley medium} // &{tfrain github}
评论