Go rejects unused local variables and unused imports. That catches mistakes early and keeps builds fast. The blank identifier _ can import a package for side effects only, or discard a value you must read for effect, but shadowing with := inside if / else is a common reason a variable looks “used” but still errors—see the third example. For scope rules, see variable scope in Go.
Tested with Go 1.24 on Linux.
imported and not used
package main
import (
"fmt"
_ "encoding/json"
)
func main() {
name := "GoLinuxCloud"
age := 1
fmt.Println("My name is:", name, "and my age is:", age)
}Remove encoding/json entirely if you do not need it, or keep _ when the package must register codecs or similar in init.
declared and not used on a variable
package main
import "fmt"
func main() {
page := "GoLinuxCloud"
author := "Anonymous Author"
fmt.Println("Page is:", page)
_ = author
}Prefer deleting author or printing it; _ = author is only for transitional code.
Shadowing with := inside branches
If you write boolStr := "True" inside an if or else block, that := introduces a new variable scoped only to that block. The outer boolStr you meant to print stays at its zero value and triggers declared and not used. Assign to the outer name with = instead:
package main
import "fmt"
func main() {
var boolStr string
if false {
boolStr = "False"
} else {
boolStr = "True"
}
fmt.Println(boolStr)
}You should see True.
Summary
The messages declared and not used and imported and not used mean the compiler sees no read of a binding or package. Fix real unused code first; use _ imports only for documented side effects; in branches, use = on existing names so you do not accidentally declare a shadowed variable. An IDE such as VS Code with the Go extension flags many of these before go build (getting started with Go).

