gitee.com/quant1x/num@v0.3.2/binary/bytes.go (about) 1 package binary 2 3 import ( 4 "gitee.com/quant1x/num/kind" 5 "math" 6 "unsafe" 7 _ "unsafe" 8 ) 9 10 //go:linkname Repeat bytes.Repeat 11 func Repeat(b []byte, count int) []byte 12 13 // ToBytes x的内存空间直接转成字节切片 14 func ToBytes[E kind.BaseType](x E) []byte { 15 return v0ToBytes(x) 16 } 17 18 // TODO: 内存操作demo 19 func f64ToBytes(x float64) []byte { 20 ptr := unsafe.Pointer(&x) 21 b := (*[8]byte)(ptr)[:] 22 return b 23 } 24 25 // 性能和v1ToBytes_nocopy接近 26 func v0ToBytes[E kind.BaseType](x E) []byte { 27 ptr := unsafe.Pointer(&x) 28 switch v := any(x).(type) { 29 case bool, int8, uint8: // bool, byte, int8, uint8 30 return (*[1]byte)(ptr)[:] 31 case int16, uint16: // int16, uint16, word(windows) 32 return (*[2]byte)(ptr)[:] 33 case int32, uint32, float32: // int32, uint32, float32, rune(int32), dword(windows) 34 return (*[4]byte)(ptr)[:] 35 case int64, uint64, int, uintptr, float64, complex64: // int64, uint64, int, uintptr, float64, complex64 36 return (*[8]byte)(ptr)[:] 37 case complex128: // complex128 38 return (*[16]byte)(ptr)[:] 39 case string: // string 40 // unsafe.SizeOf("") == 16, 需要单独处理, 不能按照类型的SizeOf返回值类处理 41 return unsafe.Slice(unsafe.StringData(v), len(v)) 42 } 43 //panic(fmt.Errorf("unsupported type: %T", x)) 44 panic("unsupported type") 45 } 46 47 // 性能和v1ToBytes_nocopy接近 48 // 存在bug, unsafe.SizeOf("") == 16 49 func v0ToBytes1[E kind.BaseType](x E) []byte { 50 size := int(unsafe.Sizeof(x)) 51 ptr := unsafe.Pointer(&x) 52 switch size { 53 case 1: // bool, byte, int8, uint8 54 return (*[1]byte)(ptr)[:] 55 case 2: // int16, uint16, word 56 return (*[2]byte)(ptr)[:] 57 case 4: // int32, uint32, dword, float32 58 return (*[4]byte)(ptr)[:] 59 case 8: // int64, uint64, int, uintptr, flot64, complex64 60 return (*[8]byte)(ptr)[:] 61 case 16: // complex128 string 62 return (*[16]byte)(ptr)[:] 63 default: 64 } 65 //panic(fmt.Errorf("unsupported type: %T", x)) 66 panic("unsupported type") 67 } 68 69 func v1ToBytes_copy[T kind.BaseType](x T) []byte { 70 size := int(unsafe.Sizeof(x)) 71 var v SliceHeader 72 v.Len = size 73 v.Cap = size 74 v.Data = uintptr(unsafe.Pointer(&x)) 75 d := *(*[]byte)(unsafe.Pointer(&v)) 76 // TODO: 下面可能是delve的bug 77 // 在GoLand调试时, 如果不进行copy, 那么后续操作中内存一定会被覆盖 78 data := make([]byte, size) 79 copy(data[:size], d[:size]) 80 return data 81 } 82 83 func v1ToBytes_nocopy[T kind.BaseType](x T) []byte { 84 size := int(unsafe.Sizeof(x)) 85 ptr := unsafe.Pointer(&x) 86 var v SliceHeader 87 v.Len = size 88 v.Cap = size 89 v.Data = uintptr(ptr) 90 d := *(*[]byte)(unsafe.Pointer(&v)) 91 return d 92 } 93 94 func v2ToBytes[T kind.BaseType](x T) []byte { 95 b := make([]byte, unsafe.Sizeof(x)) 96 endian := defaultByteOrder() 97 switch v := any(x).(type) { 98 case float64: 99 u64 := math.Float64bits(v) 100 endian.PutUint64(b, u64) 101 } 102 return b 103 } 104 105 func v3ToBytes[E kind.BaseType](x E) []byte { 106 size := unsafe.Sizeof(x) 107 ptr := unsafe.Pointer(&x) 108 b := (*[1]byte)(ptr)[:] 109 return unsafe.Slice(&b[0], size) 110 } 111 112 // ToSlice 内存空间字节数组直接转成泛型切片 113 func ToSlice[T kind.BaseType](data []byte, n int) []T { 114 if n < 1 { 115 return []T{} 116 } 117 return v1ToSlice[T](data, n) 118 } 119 120 func v0ToSlice[T kind.BaseType](data []byte, n int) []T { 121 ptr := unsafe.Pointer(&data[0]) 122 b := (*[1]T)(ptr)[:] 123 return unsafe.Slice(&b[0], n) 124 } 125 126 func v1ToSlice[T kind.BaseType](data []byte, n int) []T { 127 var v SliceHeader 128 v.Len = n 129 v.Cap = n 130 v.Data = uintptr(unsafe.Pointer(&data[0])) 131 return *(*[]T)(unsafe.Pointer(&v)) 132 }