Lexical elements: Comments
January 9, 2023
Let’s talk about comments!
This might seem like a pretty dull topic, but there are actually a few nuances in here that even I learned while reading.
Lexical elements
Comments
Comments serve as program documentation. There are two forms:
- Line comments start with the character sequence
//
and stop at the end of the line.- General comments start with the character sequence
\*
and stop with the first subsequent character sequence\*
.
Simple enough. We have two comment forms:
// This is "Line comment"
/* This is "General comment */
A comment cannot start inside a rune or string literal, or inside a comment. A general comment containing no newlines acts like a space. Any other comment acts like a newline.
This clarification offers some mildly interesting nuances. Let’s break it down.
A comment cannot start inside a rune or string literal.
Seems pretty straight forward. A rune literal means a rune surrounded by single quotes ('
), so this is not a valid comment:
var someRune = '/* invalid comment */x'
And a string literal is similarly intuitive, although there are two forms, which we’ll get into later.
var someString = "/* this is part of the string, not a comment */string"
A comment cannot start … inside a comment.
One might think it’s silly to say a comment cannot start inside a comment, but it actually does have a practical significance to indicate so explicitly, as it means the following examples are not valid:
// A line comment cannot contain the /* beginning of a general comment
this line is not part of a comment, so would cause a syntax error */
/* You cannot have /* nested */ comments */
The part I find most interesting, however, is the last two sentences:
A general comment containing no newlines acts like a space. Any other comment acts like a newline.
This means it is quite possible to put general comments mid-statement, and it will be valid:
if err /* network error? */ != nil {
return err
}
This would be interpreted as:
if err != nil {
return err
}
Which is perfectly valid. Cool.
What doesn’t work, is to include a general comment in the middle of a numeric literal, which one might think since rune and string literals are explicitly called out as invalid.
x := 1/* thousand! */000
Will be interpreted as
x := 1 000
which is invalid.
Although, you can still use general comments between literals and operators, for example:
const foo = 1 /* a comment */ + iota
Of course, there’s still the question whether one ever should do these things. I’m of the opinion that comments (other than GoDoc style comments, which we’ll come to) should be sparse, and we should aim for self-documenting code as much as possible. But that’s quite another topic from what the language allows, of course.
Quotes from The Go Programming Language Specification, Version of June 29, 2022