0

I believe there is a slight problem with the Go specification. The following complains that the array literal is not addressable:

    print([4]int{2,3}[:2])

I know why an array returned from a function is not addressable (eg Error addressing the returned slice of a function) but why is an array literal like [4]int{2,3} not addressable? Especially when slice and string literals are - eg these work fine:

    print([]int{2,3,0,0}[:2])
    print("2300"[:2])

Moreover, array literals do seem to be addressable since &[4]int{42,43} is a valid expression.

I know I can use a slice

    print([]int{2,3,0,0}[:2])

but what if I wanted the capacity (array length) to be a compile-time constant.

    const maxLength = 4
    ...
    print([maxLength]int{2,3}[:2])

And yes I can assign to a temporary array variable, but why do I need to?

AJR
  • 1,547
  • 5
  • 16
  • Literals aren't addressable because they're literals; they're evaluated at compile time, they don't exist in memory at runtime until they're assigned to a value (variable/argument/etc). When you add `&` to get a pointer you're creating a *composite literal*, which forces a value to be created at runtime when it's evaluated: "Composite literals construct values for structs, arrays, slices, and maps and create a new value each time they are evaluated." – Adrian Feb 10 '20 at 14:53
  • Thanks @Adrian. Yes I assumed that literals are not addressable but then I tried slice and string literals and they work (as I mentioned in my original question). BTW I did read the GO spec. but it was unclear or I am a bit thick (more likely). – AJR Feb 10 '20 at 22:18

1 Answers1

5

Use the following:

fmt.Println((&[4]int{2, 3})[:2])

The specification says this about slice expressions:

If the sliced operand is an array, it must be addressable.

and this about addressability:

The operand must be addressable, that is, either a variable, pointer indirection, or slice indexing operation; or a field selector of an addressable struct operand; or an array indexing operation of an addressable array. As an exception to the addressability requirement, x may also be a (possibly parenthesized) composite literal.

The array is not addressable, but the composite literal exception can be used to get an addressable value.

Array operands must be addressable because the elements of the resulting slice are addressable. String operands are not required to be addressable because string elements are never addressable.

Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • Thanks for the workaround! BTW I did read the spec. but wasn't sure I understood it as to me it seems a string literal (eg `"2300"[:2]`) should have the same problem. – AJR Feb 10 '20 at 22:24
  • 1
    @AJR I added an explanation to the answer. – Charlie Tumahai Feb 10 '20 at 22:58