go: reflect: permit Value.Bytes (but not SetBytes) on addressable byte arrays

I’m trying to get a []byte of an array via reflect, without allocations.

reflect.Value.Bytes says:

Bytes returns v’s underlying value. It panics if v’s underlying value is not a slice of bytes.

I have an array, not a slice. I can slice it, but reflect.Value.Slice call allocates:

func TestArraySliceAllocs(t *testing.T) {
        type T struct {
                X [32]byte
        }
        x := &T{X: [32]byte{1: 1, 2: 2, 3: 3, 4: 4}}

        var b []byte
        n := int(testing.AllocsPerRun(2000, func() {
                v := reflect.ValueOf(x)
                b = v.Elem().Field(0).Slice(0, 5).Bytes()
        }))
        if n != 0 {
                t.Errorf("allocs = %d; want 0", n)
        }
        const want = "\x00\x01\x02\x03\x04"
        if string(b) != want {
                t.Errorf("got %q; want %q", b, want)
        }
}

(fails with 1 alloc, from Slice)

Perhaps reflect.Value.Bytes could also permit getting a []byte of an array of bytes?

Or maybe I’m holding reflect wrong and there’s an alloc-free way to do this already.

/cc @josharian

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 3
  • Comments: 23 (20 by maintainers)

Commits related to this issue

Most upvoted comments

I see. I think it would be fine to allow Bytes to work on an addressable array (or pointer to array?).