Compile errors
In the previous lesson the compiler was a strict proofreader who keeps a recipe with a mistake out of the kitchen. Now let's see how it reports what it found, and which rules Go checks more strictly than other languages.
Go does not build a program that declares a variable inside a function and never uses it. The line n := 10 creates a variable n—a name that holds the value 10—but the program never reads it afterward:
package main
import "fmt"
func main() {
n := 10 // ✗
fmt.Println("ok")
}declared and not used: nThis is a compile error: the compiler refused to translate the text, so the program never ran. The word ok is not printed either, even though its line is written correctly. The proofreader sent back the whole recipe, and the kitchen followed none of its steps, not even the correct ones.
The compiler's message
A proofreader returns a manuscript with notes in the margins: where the mistake is and what is wrong. The compiler does the same. The full message looks like this: ./main.go:6:5: declared and not used: n.
Let's take it apart, left to right:
./main.gois the file name.6is the line number.5is the character number within that line: on the sixth line,nstands after four spaces of indentation.declared and not used: n—after the last colon, the compiler says exactly which rule is broken.
If there are several errors, the compiler lists them one per line. Fix them from top to bottom: the later ones in the list sometimes disappear together with the first.
Two build commands
You can build a program with two commands. They treat the result differently, so let's look at each on its own.
go build: build only
The command go build main.go has three parts:
gois the tool that is installed together with the language;buildis the action "build";main.gois the file with the program.
Without errors, the command creates a finished program in the folder you ran it from. The file is named after the source file without .go: main.go gives main, and on Windows main.exe.
You run the program separately, as many times as you like, without compiling it again. On a compile error, no program file is created.
go run: build and run
The command go run main.go compiles the program the same way as go build and runs the result right away. No finished program file appears in the folder.
This command is handy while you are writing a program and checking what it prints: one step instead of two. On a compile error, it runs nothing.
Errors, not warnings
In many languages, the compiler issues warnings besides errors: a program with warnings builds, but the suspicious spot is marked. That is like a proofreader who writes "check this" in the margin and sends the text to print anyway.
Go's proofreader never does that: Go has no warnings, and everything the compiler finds is an error. An unused variable is one of those errors. It often reveals the author's slip: a value was computed but never printed or passed on.
Interviewers like to ask: what happens if you declare a variable and never read it? Here are the three answers you usually hear:
- "the program does not compile"—right;
- "it prints a warning"—wrong: Go has no warnings;
- "it fails at run time"—wrong: it never gets as far as running.
Two ways to fix it
You can fix an unused variable in two ways. The choice depends on whether the program needs its value.
Read the variable
If the value is needed, you use it—for example, print it:
package main
import "fmt"
func main() {
n := 10
fmt.Println(n) // 10
}Now n is used: fmt.Println(n) reads the variable and prints 10. The compiler has nothing left to object to, and the program runs.
Delete the line
If the value is not needed, you delete the line n := 10 entirely. In the first example, only fmt.Println("ok") is then left, and the program prints ok.
Common mistake
The same rule applies to imports: a package that is imported but never used stops the build. This happens when the last call to fmt.Println is removed from a program but the import stays:
package main
import "fmt" // ✗
func main() {
}"fmt" imported and not usedThe fix is to delete the line import "fmt": no call to the package fmt is left in the program.
Key points
- A compile error stops the build: the program does not run, and not a single line executes.
- The message names the file, the line and the character, and after the last colon the broken rule.
- Go has no warnings: an unused variable inside a function and an unused import are errors.
go buildonly compiles a program, whilego runcompiles it and runs it right away.
Subscribe to take the course
The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.