【问题标题】:How to convert slice to fixed size array? [duplicate]如何将切片转换为固定大小的数组? [复制]
【发布时间】:2015-07-28 22:09:36
【问题描述】:

我想从一个切片转换一个固定大小的数组:

func gen(bricks []Brick) {
    if len(bricks) == 16 {
        if check(Sculpture{bricks}) {
            var b [16]Brick = bricks[0:16];
        }
     }
}

但这会导致:

 cannot use bricks[0:16] (type []Brick) as type [16]Brick in assignment

如何将切片转换为固定大小的数组?

【问题讨论】:

    标签: arrays go slice


    【解决方案1】:

    编辑:从 Go 1.17 开始,您可以使用对切片到数组转换的新支持:https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer

    Go 1.16 及以下版本的先前答案:

    你需要使用copy:

    slice := []byte("abcdefgh")
    
    var arr [4]byte
    
    copy(arr[:], slice[:4])
    
    fmt.Println(arr)
    

    正如 Aedolon 所说,您也可以只使用

    copy(arr[:], slice)
    

    因为副本将始终只复制len(src)len(dst) 字节中的最小值。

    【讨论】:

    • 这是正确的,但有一点补充:你不需要copy(arr[:], slice[:4])copy(arr[:], slice) 就足够了。 copy 自动将自身限制为给定切片中较小的一个。
    • @Aedolon 感谢您的提示,已将其添加到答案中。
    • 不错的答案,真的。
    • 注意从 Golang 1.17 开始你可以使用tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer
    • @ChrisSmowton 请将其编辑为我的答案或发布新的答案,就好像有一种更新的方式应该是正确的答案,而不仅仅是评论。
    【解决方案2】:

    我找到了一种无需分配更多空间即可解决问题的方法 - 定义一个与 slice 具有相同结构的新结构并接收 unsafe.Pointer。

    type MySlice struct {
        Array unsafe.Pointer
        cap   int
        len   int
    }
    func main(){
        a := []byte{1, 2, 3, 4}
        fmt.Printf("a before %v, %p\n", a, &a)
        b := (*MySlice)(unsafe.Pointer(&a))
        c := (*[4]byte)(b.Array)
        fmt.Printf("c before %v, %T, %p\n", *c, *c, c)
        a[1] = 5
        fmt.Printf("c after %v, %p\n", *c, c)
        fmt.Printf("a after %v, %p\n", a, &a)
    }
    

    结果如下:

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-09-04
    • 1970-01-01
    • 2019-06-15
    • 2019-05-14
    • 2020-12-01
    相关资源
    最近更新 更多