Constant expressions

March 15, 2024

We made it through all the conversion rules! Let’s change gear and talk about…

Constant expressions

Constant expressions may contain only constant operands and are evaluated at compile time.

Or framed differently: Any expression that contains non-constant operands, is not a constant expression.

If you have a constant expression (e.g. 1 + 2) then extend it with a non-constant operand (e.g. 1 + 2 + userCount()), then it is no longer a constant expression.

(Actually, in this example, we have a non-constant expression made up of two operands, one of which is itself a constant expression 1 + 2, and the other which is the non-constant expression userCount()).

Untyped boolean, numeric, and string constants may be used as operands wherever it is legal to use an operand of boolean, numeric, or string type, respectively.

A constant comparison always yields an untyped boolean constant. If the left operand of a constant shift expression is an untyped constant, the result is an integer constant; otherwise it is a constant of the same type as the left operand, which must be of integer type.

Any other operation on untyped constants results in an untyped constant of the same kind; that is, a boolean, integer, floating-point, complex, or string constant. If the untyped operands of a binary operation (other than a shift) are of different kinds, the result is of the operand’s kind that appears later in this list: integer, rune, floating-point, complex. For example, an untyped integer constant divided by an untyped complex constant yields an untyped complex constant.

All of this is just to explain the resulting type of a constant expression, which matters when composing complex expressions, or assigning to a variable, for example.

We’ll end today with a long table of examples:

const a = 2 + 3.0          // a == 5.0   (untyped floating-point constant)
const b = 15 / 4           // b == 3     (untyped integer constant)
const c = 15 / 4.0         // c == 3.75  (untyped floating-point constant)
const Θ float64 = 3/2      // Θ == 1.0   (type float64, 3/2 is integer division)
const Π float64 = 3/2.     // Π == 1.5   (type float64, 3/2. is float division)
const d = 1 << 3.0         // d == 8     (untyped integer constant)
const e = 1.0 << 3         // e == 8     (untyped integer constant)
const f = int32(1) << 33   // illegal    (constant 8589934592 overflows int32)
const g = float64(2) >> 1  // illegal    (float64(2) is a typed floating-point constant)
const h = "foo" > "bar"    // h == true  (untyped boolean constant)
const j = true             // j == true  (untyped boolean constant)
const k = 'w' + 1          // k == 'x'   (untyped rune constant)
const l = "hi"             // l == "hi"  (untyped string constant)
const m = string(k)        // m == "x"   (type string)
const Σ = 1 - 0.707i       //            (untyped complex constant)
const Δ = Σ + 2.0e-4       //            (untyped complex constant)
const Φ = iota*1i - 1/1i   //            (untyped complex constant)

Quotes from The Go Programming Language Specification Language version go1.22 (Feb 6, 2024)


Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .

Related Content


Constant expressions, part III

Did you miss yesterday’s Ask-me-anything session? You probably did. I had about 10-15 people there. But even with a small group, we had a ton of great questions! The Q&A session lasted about an hour, and covered topics such as book recommendations for going deeper into Go, what project to build to learn concurrency, and much more. Catch the replay on YouTube. Let’s continue our discussion of constant expressions, with some more miscellaneous rules:


Constant expressions, continued

Today I’ll be answering your questions on my weekly live stream. Have a question about Go? About CI/CD? About my favorite pizza toppings? Join me! Or submit your question early and catch the replay, if you can’t join live. Today we continue the section on Constant expressions, with a grab bag of miscellaneous rules. Constant expressions … Applying the built-in function complex to untyped integer, rune, or floating-point constants yields an untyped complex constant.


Constants, typed vs untyped

Constants … Constants may be typed or untyped. Now that’s interesting. And powerful. This is one of the features of Go I featured in my recent video 10 Reasons I Like Go. This feature really helps bridge the gap between the convenience of dynamically typed languages, and the safety of statically typed languages. Let’s look at the details… Literal constants, true, false, iota, and certain constant expressions containing only untyped constant operands are untyped.

Get daily content like this in your inbox!

Subscribe