英文:
How to convert slice to fixed size array?
问题
我想将一个固定大小的数组从切片转换为:
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
如何将切片转换为固定大小的数组?
英文:
I want to convert a fixed size array from a slice:
func gen(bricks []Brick) {
if len(bricks) == 16 {
if check(Sculpture{bricks}) {
var b [16]Brick = bricks[0:16];
}
}
}
But this results in:
cannot use bricks[0:16] (type []Brick) as type [16]Brick in assignment
How to convert a slice into a fixed size array?
答案1
得分: 114
编辑:从Go 1.17开始,您可以使用新的切片到数组指针转换支持。请参考https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer:
s := make([]byte, 2, 4)
s0 := (*[0]byte)(s) // s0 != nil
s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
s2 := (*[2]byte)(s) // &s2[0] == &s[0]
s4 := (*[4]byte)(s) // 报错:len([4]byte) > len(s)
对于Go 1.16及以下版本,您需要使用copy
函数:
slice := []byte("abcdefgh")
var arr [4]byte
copy(arr[:], slice[:4])
fmt.Println(arr)
正如Aedolon所指出的,您也可以直接使用:
copy(arr[:], slice)
因为copy
函数总是只会复制len(src)
和len(dst)
中较小的字节数。
英文:
Edit: as of Go 1.17+, you may be able to use new support for slice-to-array conversions, https://tip.golang.org/ref/spec#Conversions_from_slice_to_array_pointer:
s := make([]byte, 2, 4)
s0 := (*[0]byte)(s) // s0 != nil
s1 := (*[1]byte)(s[1:]) // &s1[0] == &s[1]
s2 := (*[2]byte)(s) // &s2[0] == &s[0]
s4 := (*[4]byte)(s) // panics: len([4]byte) > len(s)
<hr>
Previous answer for Go 1.16 and below:
You need to use copy
:
slice := []byte("abcdefgh")
var arr [4]byte
copy(arr[:], slice[:4])
fmt.Println(arr)
As Aedolon notes you can also just use
copy(arr[:], slice)
as copy will always only copy the minimum of len(src)
and len(dst)
bytes.
答案2
得分: 2
我找到了一种解决问题的方法,可以在不分配任何额外空间的情况下解决问题 - 定义一个与切片具有相同结构的新结构体,并接收 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)
}
结果如下所示:
英文:
I found a way to solve the problem without allocating any more space - to define a new struct with the same construction as slice and receive the 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)
}
the result shows as follows:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论