如标题所描述对一下两者进行相互的装换,在不使用 copy 的情况下:
var array [1024]byte
var slice []byte
1
accidentaly OP 如: array ---> slice :
slice:=array[:] 那 slice-->array? |
2
rrfeng 2020-07-08 15:54:19 +08:00
不用 copy 是为啥
|
3
accidentaly OP 因为 copy 实际上是比较慢的
|
4
blackeeper 2020-07-08 16:15:30 +08:00
@accidentaly slice-->array [...]array := slice[:]
|
5
accidentaly OP 你这样写是错的把
|
6
maoxs2 2020-07-08 16:26:12 +08:00 via Android
好像转回来必须 copy,因为 slice 地址不一定是连续的
|
7
maoxs2 2020-07-08 16:28:30 +08:00 via Android
copy 好像不算慢吧? append 这种在需要 alloc 时候才会比较慢
|
8
accidentaly OP 挺慢的,我测试过了,要求性能高的最好不要 copy
|
9
accidentaly OP slice 有一部分空间是没在被使用的 冗余空间,如果吧 slice 直接给转换成 array, 那部分冗余就可能会变成内存泄漏了,因为可能没有变量在持有他,所以 golang 不允许反过来的转换, unsafe 转化也是可以的 但是这样会造成泄漏 那就得不偿失了
|
10
kiwi95 2020-07-08 17:02:46 +08:00 via iPhone
@maoxs2 slice 底层就是数组,怎么能不是连续的,slice 转最快的是定义一个和 slice 相同的 struct,然后指针转换,但可能存在越界之类的问题
|
11
kiwi95 2020-07-08 17:04:40 +08:00 via iPhone
@kiwi95
```go func TestSlice(t *testing.T) { var s1 = []int{1, 2, 3, 4, 5} var s2 [3]int type slice struct { Arr unsafe.Pointer len int cap int } ss := *(*slice)(unsafe.Pointer(&s1)) s2 = *(*[3]int)(ss.Arr) fmt.Println("s2: ", s2) } ``` |
12
maoxs2 2020-07-08 17:17:49 +08:00 via Android
嗯是我搞错了。reflect 里那个 SliceHeader 就是你这个 struct 了,但是这样用得用 keepalive 保留原 array 不然会被 gc
|