I had planned to live stream this afternoon, but ran into some hardware problems that left me scrambling to get my PC booting again. It is now booting, and barring any other unforseen complications, I’ll be doing the planned boot.dev’s “Learn Web Servers” course next week at the regular time. I hope you can join me
Here’s one of the bits of the Go spec you probably never knew existed (I didn’t), and will never need to care about. At least after reading today’s email, you’ll be prepared for this if it ever comes up on a Go quiz at your local meetup…
Composite literals
…
A parsing ambiguity arises when a composite literal using the TypeName form of the LiteralType appears as an operand between the keyword and the opening brace of the block of an “if”, “for”, or “switch” statement, and the composite literal is not enclosed in parentheses, square brackets, or curly braces. In this rare case, the opening brace of the literal is erroneously parsed as the one introducing the block of statements. To resolve the ambiguity, the composite literal must appear within parentheses.
if x == (T{a,b,c}[i]) { … } if (x == T{a,b,c}[i]) { … }
Wow, okay. What?
First, what’s this ambiguity we see mentioned?
Let’s say we have the following type:
type T struct {
a int
}
And now we want to see if x is equal to this type with a set to 13:
if x == T{13} {
/* do a thing */
}
Looks innocent enough, right? Well, except that it might be re-formatted as:
if x == T {
13
}
{ // Whoa, what just happened here
/* do a thing */
}
So that’s the ambiguity. The {
in the composite literal looks like the beginning of the function body, not part of a composite literal.
And the solution, as mentioned, is to put parentheses around the composite literal, or (part of) the if statement containing the literal. All of these forms work:
if (x == T{13}) {
if x == (T{13}) {
if (x == T{13}) || y = nil {
Quotes from The Go Programming Language Specification Version of August 2, 2023