A few of the built-in functions are very special, in that they can evaluate to constant expressions. len
and cap
are two such functions.
But they aren’t always evaluated to constant expressions, sometimes they’re more normal-ish runtime functions.
Length and capacity
…
The expression
len(s)
is constant ifs
is a string constant. The expressionslen(s)
andcap(s)
are constants if the type ofs
is an array or pointer to an array and the expressions
does not contain channel receives or (non-constant) function calls; in this case s is not evaluated. Otherwise, invocations oflen
andcap
are not constant ands
is evaluated.const ( c1 = imag(2i) // imag(2i) = 2.0 is a constant c2 = len([10]float64{2}) // [10]float64{2} contains no function calls c3 = len([10]float64{c1}) // [10]float64{c1} contains no function calls c4 = len([10]float64{imag(2i)}) // imag(2i) is a constant and no function call is issued c5 = len([10]float64{imag(z)}) // invalid: imag(z) is a (non-constant) function call ) var z complex128
The example provided in the spec demonstrates a few examples of constant len()
expressions by assigning the results to constants. But the fact that len()
and cap()
may resolve to constants has much more broad application.
First, it can be a simple compiler optimization to use constant expressions, rather than variable expressions, where possible. Take for example, something as simple as:
fmt.Println(len(x))
If the compiler is able to, according to the rules above, it will evaluate len(x)
as a constant, and thus save the effort of calculating it every time the program runs this line of code. For something simple like a print statement, such an optimization is pretty accademic. But in some cases, such an optimization can be significant. And every little optimization adds up.
Quotes from The Go Programming Language Specification Language version go1.23 (June 13, 2024)