如何将切片转换为固定大小的数组?
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
如何将切片转换为固定大小的数组?
编辑:从 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) // panics: 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)
因为副本将始终只复制 len(src)
和 len(dst)
字节中的最小值。
我找到了解决问题的方法,无需再分配 space - 定义一个与 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)
}
结果如下:
我想从一个切片中转换一个固定大小的数组:
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
如何将切片转换为固定大小的数组?
编辑:从 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) // panics: 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)
因为副本将始终只复制 len(src)
和 len(dst)
字节中的最小值。
我找到了解决问题的方法,无需再分配 space - 定义一个与 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)
}
结果如下: