V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
accidentaly
V2EX  ›  问与答

golang 中 array 和 slice 互相转化

  •  
  •   accidentaly · 2020-07-08 15:33:23 +08:00 · 3489 次点击
    这是一个创建于 1606 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如标题所描述对一下两者进行相互的装换,在不使用 copy 的情况下:

    var array [1024]byte

    var slice []byte

    12 条回复    2020-07-08 17:17:49 +08:00
    accidentaly
        1
    accidentaly  
    OP
       2020-07-08 15:53:15 +08:00
    如: array ---> slice :
    slice:=array[:]

    那 slice-->array?
    rrfeng
        2
    rrfeng  
       2020-07-08 15:54:19 +08:00
    不用 copy 是为啥
    accidentaly
        3
    accidentaly  
    OP
       2020-07-08 16:14:58 +08:00
    因为 copy 实际上是比较慢的
    blackeeper
        4
    blackeeper  
       2020-07-08 16:15:30 +08:00
    @accidentaly slice-->array [...]array := slice[:]
    accidentaly
        5
    accidentaly  
    OP
       2020-07-08 16:22:11 +08:00
    你这样写是错的把
    maoxs2
        6
    maoxs2  
       2020-07-08 16:26:12 +08:00 via Android
    好像转回来必须 copy,因为 slice 地址不一定是连续的
    maoxs2
        7
    maoxs2  
       2020-07-08 16:28:30 +08:00 via Android
    copy 好像不算慢吧? append 这种在需要 alloc 时候才会比较慢
    accidentaly
        8
    accidentaly  
    OP
       2020-07-08 16:57:46 +08:00
    挺慢的,我测试过了,要求性能高的最好不要 copy
    accidentaly
        9
    accidentaly  
    OP
       2020-07-08 16:58:37 +08:00
    slice 有一部分空间是没在被使用的 冗余空间,如果吧 slice 直接给转换成 array, 那部分冗余就可能会变成内存泄漏了,因为可能没有变量在持有他,所以 golang 不允许反过来的转换, unsafe 转化也是可以的 但是这样会造成泄漏 那就得不偿失了
    kiwi95
        10
    kiwi95  
       2020-07-08 17:02:46 +08:00 via iPhone
    @maoxs2 slice 底层就是数组,怎么能不是连续的,slice 转最快的是定义一个和 slice 相同的 struct,然后指针转换,但可能存在越界之类的问题
    kiwi95
        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)
    }
    ```
    maoxs2
        12
    maoxs2  
       2020-07-08 17:17:49 +08:00 via Android
    嗯是我搞错了。reflect 里那个 SliceHeader 就是你这个 struct 了,但是这样用得用 keepalive 保留原 array 不然会被 gc
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   945 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 20:32 · PVG 04:32 · LAX 12:32 · JFK 15:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.