133 lines
4.1 KiB
Go
133 lines
4.1 KiB
Go
package code
|
||
|
||
import (
|
||
"fmt"
|
||
"reflect"
|
||
"testing"
|
||
"unsafe"
|
||
|
||
"github.com/stretchr/testify/assert"
|
||
)
|
||
|
||
func TestSliceArray(t *testing.T) {
|
||
var arr = [...]int{1, 2, 3}
|
||
var slice = []int{1, 2, 3}
|
||
ModifyArray(arr)
|
||
ModifySlice(slice)
|
||
t.Logf("%v %v\n", arr, slice)
|
||
assert.NotEqual(t, arr[2], 1)
|
||
assert.Equal(t, slice[2], 1)
|
||
}
|
||
|
||
func ModifyArray(arr [3]int) {
|
||
fmt.Println(arr)
|
||
arr[2] = 1
|
||
}
|
||
|
||
func ModifySlice(slice []int) {
|
||
fmt.Println(slice)
|
||
slice[2] = 1
|
||
}
|
||
|
||
func TestSlice(t *testing.T) {
|
||
slice := []int{1, 2, 3}
|
||
arr := [...]int{1, 2, 3}
|
||
fmt.Printf("切片:底层数组指针:%d 切片:指针%v reflect.SliceHeader: %+v\n",
|
||
unsafe.SliceData(slice), unsafe.Pointer(&slice), (*reflect.SliceHeader)(unsafe.Pointer(&slice)))
|
||
SlicePointer(slice)
|
||
fmt.Printf("数组:底层数组指针:%d 数组指针:%d\n", unsafe.Pointer(&arr), unsafe.Pointer(&arr[0]))
|
||
ArrayPointer(arr)
|
||
}
|
||
|
||
func SlicePointer(slice []int) {
|
||
fmt.Printf("切片:底层数组指针:%d 切片:指针%v reflect.SliceHeader: %+v\n",
|
||
unsafe.SliceData(slice), unsafe.Pointer(&slice), (*reflect.SliceHeader)(unsafe.Pointer(&slice)))
|
||
}
|
||
|
||
func ArrayPointer(arr [3]int) {
|
||
fmt.Printf("数组:底层数组指针:%d 数组指针:%d\n", unsafe.Pointer(&arr), unsafe.Pointer(&arr[0]))
|
||
}
|
||
|
||
func TestModify(t *testing.T) {
|
||
arr := [...]int{1, 2, 3, 4, 5, 6, 7}
|
||
slice := arr[:]
|
||
slice[4] = 8
|
||
t.Logf("arr[4]=%v,slice[4]=%v\n", arr[4], slice[4])
|
||
assert.Equal(t, slice[4], arr[4])
|
||
slice = append(slice, 9)
|
||
slice[5] = 10
|
||
t.Logf("arr[4]=%v,slice[4]=%v\n", arr[4], slice[4])
|
||
assert.Equal(t, slice[4], arr[4])
|
||
t.Logf("arr[5]=%v,slice[5]=%v\n", arr[5], slice[5])
|
||
assert.NotEqual(t, slice[5], arr[5])
|
||
}
|
||
|
||
func TestModifyTwoSlice(t *testing.T) {
|
||
arr := [...]int{1, 2, 3, 4, 5, 6, 7, 8, 9}
|
||
slice1 := arr[1:5]
|
||
slice2 := arr[3:8]
|
||
slice1[2] = 8
|
||
t.Logf("%v %v %v\n", arr, slice1, slice2)
|
||
assert.Equal(t, slice1[2], slice2[0], arr[3])
|
||
}
|
||
|
||
func TestCap(t *testing.T) {
|
||
slice := []int{1, 2, 3, 4}
|
||
fmt.Printf("len:%d cap: %d\n", len(slice), cap(slice))
|
||
slice = append(slice, make([]int, 11)...)
|
||
fmt.Printf("len:%d cap: %d\n", len(slice), cap(slice)) // oldcap<256,直接使用新切片容量
|
||
slice = append(slice, make([]int, 260)...)
|
||
fmt.Printf("len:%d cap: %d\n", len(slice), cap(slice)) // oldcap<256,直接使用新切片容量
|
||
slice = append(slice, make([]int, 250)...)
|
||
fmt.Printf("len:%d cap: %d\n", len(slice), cap(slice)) // 1.25倍循环扩容
|
||
}
|
||
|
||
func TestString(t *testing.T) {
|
||
str := "hello"
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
str = "world"
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
str = str[:3]
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
}
|
||
|
||
func TestStringAsSlice(t *testing.T) {
|
||
str := "hello,world"
|
||
hello := str[:5]
|
||
world := str[6:]
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
fmt.Printf("%d %+v\n", &hello, (*reflect.StringHeader)(unsafe.Pointer(&hello)))
|
||
fmt.Printf("%d %+v\n", &world, (*reflect.StringHeader)(unsafe.Pointer(&world)))
|
||
}
|
||
|
||
func TestCopy(t *testing.T) {
|
||
str := "hello,world"
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
b := []byte(str)
|
||
fmt.Printf("%d %+v\n", unsafe.Pointer(&b), (*reflect.SliceHeader)(unsafe.Pointer(&b)))
|
||
}
|
||
|
||
func TestZeroCopy(t *testing.T) {
|
||
str := "hello,world"
|
||
fmt.Printf("%d %+v\n", &str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
b := unsafe.Slice(unsafe.StringData(str), len(str))
|
||
fmt.Printf("%s %+v\n", b, (*reflect.SliceHeader)(unsafe.Pointer(&b)))
|
||
}
|
||
|
||
func TestConvertZeroCopy(t *testing.T) {
|
||
n := []int64{1, 2, 3, 4}
|
||
// 注意精度问题
|
||
fmt.Printf("%+v\n", (*reflect.SliceHeader)(unsafe.Pointer(&n)))
|
||
f := unsafe.Slice(unsafe.SliceData(n), len(n))
|
||
fmt.Printf("%v %+v\n", f, (*reflect.SliceHeader)(unsafe.Pointer(&f)))
|
||
}
|
||
|
||
func TestReplace(t *testing.T) {
|
||
str := "hello,world"
|
||
fmt.Printf("%v %+v\n", str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
b := []byte(str)
|
||
b[1] = 'a'
|
||
str = unsafe.String(unsafe.SliceData(b), len(b))
|
||
fmt.Printf("%v %+v\n", str, (*reflect.StringHeader)(unsafe.Pointer(&str)))
|
||
}
|