How to convert slice to fixed size array? [duplicate]

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?


Solution 1:

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

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.

Solution 2:

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: result