golang面试题:字符串转成byte数组,会发生内存拷贝吗
在一个公众号上看到一个这个题 虽然知道会发生拷贝, 但不知道还有这种方式来解决,转载一下以作记录。
我们知道字符串转成切片,会产生拷贝。严格来说,只要是发生类型强转都会发生内存拷贝。那么问题来了。 频繁的内存拷贝操作听起来对性能不大友好。有没有什么办法可以在字符串转成切片的时候不用发生拷贝呢?
package main\
\
import (\
"fmt"\
"reflect"\
"unsafe"\
)\
\
func main() {\
a :="aaa"\
ssh := *(*reflect.StringHeader)(unsafe.Pointer(&a))\
b := *(*[]byte)(unsafe.Pointer(&ssh)) \
fmt.Printf("%v",b)\
}
StringHeader
是字符串
在go的底层结构。
type StringHeader struct {
Data uintptr
Len int
}
SliceHeader
是切片
在go的底层结构。
type SliceHeader struct {
Data uintptr
Len int
Cap int
}
- 那么如果想要在底层转换二者,只需要把
StringHeader
的地址强转成SliceHeader
就行。那么go有个很强的包叫unsafe
。 -
- 1.
unsafe.Pointer(&a)
方法可以得到变量a
的地址。 - 2.
(*reflect.StringHeader)(unsafe.Pointer(&a))
可以把字符串a转成底层结构的形式。 - 3.
(*[]byte)(unsafe.Pointer(&ssh))
可以把ssh底层结构体转成byte的切片的指针。 - 4.再通过
*
转为指针指向的实际内容。
- 1.
补充:
float 类型可以作为 map 的 key 吗
任何类型都可以作为 value,包括 map 类型。 但是当用 float64 作为 key 的时候,先要将其转成 unit64 类型,再插入 key 中。
具体是通过 Float64frombits
函数完成:
// Float64frombits returns the floating point number corresponding
// the IEEE 754 binary representation b.
func Float64frombits(b uint64) float64 {
return *(*float64)(unsafe.Pointer(&b))
}
也就是将浮点数表示成 IEEE 754 规定的格式。如赋值语句:
0x00bd 00189 (test18.go:9) LEAQ "".statictmp_0(SB), DX0x00c4 00196 (test18.go:9) MOVQ DX, 16(SP)0x00c9 00201 (test18.go:9) PCDATA $0, $20x00c9 00201 (test18.go:9) CALL runtime.mapassign(SB)
"".statictmp_0(SB)
变量是这样的:
"".statictmp_0 SRODATA size=8 0x0000 33 33 33 33 33 33 03 40"".statictmp_1 SRODATA size=8 0x0000 ff 3b 33 33 33 33 03 40"".statictmp_2 SRODATA size=8 0x0000 33 33 33 33 33 33 03 40
我们再来输出点东西:
package mainimport ( "fmt" "math")
func main() {
m := make(map[float64]int)
m[2.4] = 2
fmt.Println(math.Float64bits(2.4))
fmt.Println(math.Float64bits(2.400000000001))
fmt.Println(math.Float64bits(2.4000000000000000000000001))}
461258673835286200346125867383528642554612586738352862003
转成十六进制为:
0x40033333333333330x4003333333333BFF0x4003333333333333
和前面的 "".statictmp_0
比较一下,2.4
和 2.4000000000000000000000001
经过 math.Float64bits()
函数转换后的结果是一样的。自然,二者在 map 看来,就是同一个 key 了。
转载自:https://juejin.cn/post/7048508847647883271