-2

I used the go playground to try this code:

package main

func main() {
    exp := []string{"HELLO"}

    const length = len(exp)
}

But it is throwing me this error:

./prog.go:6:8: const initializer len(exp) is not a constant

I can see that this is happening because the length of exp is changeable. How can i get the current length and store it in an integer constant?

I would think that I need the reflect module to do this, but I don't know how to do it. I tried using reflect.ValueOf but it did not work.

exp := []string{"HELLO"}
const length = len(reflect.ValueOf(exp).Interface().([]string))
Ank i zle
  • 2,089
  • 3
  • 14
  • 36

1 Answers1

6

You can indeed get the current length, but that is by definition not a constant. Here is what the language specification has to say about this:

The expression len(s) is constant if s is a string constant. The expressions len(s) and cap(s) are constants if the type of s is an array or pointer to an array and the expression s does not contain channel receives or (non-constant) function calls; in this case s is not evaluated. Otherwise, invocations of len and cap are not constant and s is evaluated.

Since your invocation of len is as len(exp) we must test exp against the text above:

  • Is it a string constant? No; it is a slice.
  • Is it an array? No; it is a slice.
  • Is it a pointer to an array? No, it is a slice.

The three cases where len would produce a constant have been exhausted, so len must necessarily produce a non-constant.

If you would like len to produce a constant, you will have to apply it to a string constant, or an array, or a pointer to an array. Arrays are similar in many ways to slices, so this is possible. For instance, in your example, simply replacing:

exp := []string{"HELLO"}

with:

exp := [1]string{"HELLO"}

suffices. Should you wish the compiler to count the initializers, using ... suffices:

exp := [...]string{"HELLO"}

See example on Go Playground. Note that because exp is now an array, not a slice, some operations cannot be performed on/with exp.

torek
  • 448,244
  • 59
  • 642
  • 775