byte与string底层强转

go 中byte与string的底层转换及问题

普通强转

用关键字进行强转,底层会发生拷贝,两个变量互不影响。
代码示例:

	s:="012345"
	b:=[]byte(s)
	s1:=string(b)
	fmt.Println(s1)
	b[0]='9'
	fmt.Println(s1)
=== RUN   Test_强转
012345
012345
--- PASS: Test_强转 (0.00s)
PASS

运用底层编程强转

1 byte to string

go支持中文字符做为变量

func Test_运用底层编程byteToString(t *testing.T) {
	var b = []byte{'1', '2', '3', '4'}
	s := *(*string)(unsafe.Pointer(&b))
	fmt.Println(s)
}
=== RUN   Test_运用底层编程byteToString存在的问题
1234
--- PASS: Test_运用底层编程byteToString存在的问题 (0.00s)
PASS

存在问题
由于底层没有copy,导致字符串并不是常量。在常规理解中,字符串一经生成,便不会改变,经底层强转后字符串变得可以改变。虽然用底层强转效率变高,但是也产生了新问题。

func Test_运用底层编程byteToString存在的问题(t *testing.T) {

	var b = []byte{'1', '2', '3', '4'}
	s := *(*string)(unsafe.Pointer(&b))
	fmt.Println(s)
	b[0]='9'
	fmt.Println(s)
}

=== RUN   Test_运用底层编程byteToString存在的问题
1234
9234
--- PASS: Test_运用底层编程byteToString存在的问题 (0.00s)
PASS
2 string to byte

具体实现:

func Test_StringToByte(t *testing.T) {
	var s ="1234"
	strPtr := (*[2]uintptr)(unsafe.Pointer(&s))
	res := [3]uintptr{strPtr[0], strPtr[1], strPtr[1]}
	b := *(*[]byte)(unsafe.Pointer(&res))
	fmt.Println(b)
}
=== RUN   Test_StringToByte
[49 50 51 52]
--- PASS: Test_StringToByte (0.00s)
PASS

存在问题
由于 stirng类型是常量,所以会存储在程序的常量区,这里面的数据是不容改动的,否则程序会崩溃。但我们将字符串强转成byte后,byte与string共享内存,byte可以进行修改操作是合理合规的,于是绕过了编译器的检查执行了常量区内存修改。

func Test_StringToByte存在问题(t *testing.T) {
	var s ="1234"
	strPtr := (*[2]uintptr)(unsafe.Pointer(&s))
	res := [3]uintptr{strPtr[0], strPtr[1], strPtr[1]}
	b := *(*[]byte)(unsafe.Pointer(&res))
	fmt.Println(b)
	b[0]='9'
}
=== RUN   Test_StringToByte存在问题
[49 50 51 52]
unexpected fault address 0x54a1d3
fatal error: fault
[signal 0xc0000005 code=0x1 addr=0x54a1d3 pc=0x4fe930]

goroutine 5 [running]:
runtime.throw(0x54a45a, 0x5)
	C:/Go1.12.4/src/runtime/panic.go:617 +0x79 fp=0xc00009ff08 sp=0xc00009fed8 pc=0x42e479
runtime.sigpanic()
	C:/Go1.12.4/src/runtime/signal_windows.go:236 +0x23c fp=0xc00009ff38 sp=0xc00009ff08 pc=0x4404cc
prcitf/go%e5%90%84%e7%a7%8d%e5%8f%98%e9%87%8f%e5%b8%b8%e9%87%8f%e7%b1%bb%e5%9e%8b%e5%9f%ba%e7%a1%80%e7%94%a8%e6%b3%95/string.Test_StringToByte存在问题(0xc000094100)
	D:/GO/src/prcitf/go各种变量常量类型基础用法/string/强转_test.go:56 +0xb0 fp=0xc00009ffa8 sp=0xc00009ff38 pc=0x4fe930
testing.tRunner(0xc000094100, 0x554bb0)
	C:/Go1.12.4/src/testing/testing.go:865 +0xc7 fp=0xc00009ffd0 sp=0xc00009ffa8 pc=0x4c27a7
runtime.goexit()
	C:/Go1.12.4/src/runtime/asm_amd64.s:1337 +0x1 fp=0xc00009ffd8 sp=0xc00009ffd0 pc=0x459441
created by testing.(*T).Run
	C:/Go1.12.4/src/testing/testing.go:916 +0x361

goroutine 1 [chan receive]:
testing.(*T).Run(0xc000094100, 0x550293, 0x1d, 0x554bb0, 0x472d01)
	C:/Go1.12.4/src/testing/testing.go:917 +0x388
testing.runTests.func1(0xc000094000)
	C:/Go1.12.4/src/testing/testing.go:1157 +0x7f
testing.tRunner(0xc000094000, 0xc00006be30)
	C:/Go1.12.4/src/testing/testing.go:865 +0xc7
testing.runTests(0xc0000044a0, 0x646220, 0x5, 0x5, 0x0)
	C:/Go1.12.4/src/testing/testing.go:1155 +0x2b0
testing.(*M).Run(0xc000088000, 0x0)
	C:/Go1.12.4/src/testing/testing.go:1072 +0x169
main.main()
	_testmain.go:50 +0x145

Process finished with exit code 1

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值