Source files and packages
Every Go file starts with a package declaration. Files in the same directory
must declare the same package. A program is a collection of packages; the
entry point is package main with func main().
package main
import "fmt"
func main() {
fmt.Println("hello")
}
Library packages have any other name. Their directory name should match the package name (idiom, not enforced by the compiler).
Imports
import "fmt" // single import
import (
"fmt"
"strings"
iox "io" // alias
_ "image/png" // import only for side effects (init())
. "math" // dot import — discouraged outside tests
)
Unused imports are a compile error. Use goimports (or your editor) to
auto-manage them.
Identifiers and exported names
- Identifiers are letters and digits, must start with a letter or
_. - Capitalized names are exported (visible from other packages):
fmt.Printlnis exported,fmt.printeris not. - Convention:
MixedCaps, notsnake_case. Acronyms stay uppercase (URL,ID,HTTPServer).
Comments
// Line comment.
/*
Block
comment.
*/
Doc comments are line comments immediately above an exported identifier:
// Greet returns a friendly greeting for name.
func Greet(name string) string { return "hello, " + name }
go doc and pkg.go.dev render those comments.
Declarations
Variables
var x int // zero value: 0
var y = 3.14 // type inferred: float64
var z int = 7
var ( // grouped
a = 1
b, c = "go", true
)
n := 42 // short declaration, only inside functions
:= requires at least one new variable on the left-hand side, otherwise use =.
Constants
const Pi = 3.14159
const (
KB = 1 << 10
MB = 1 << 20
GB = 1 << 30
)
iota is an auto-incrementing constant generator inside a const () block:
type Weekday int
const (
Sunday Weekday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
Zero values
Every variable in Go has a defined zero value when declared without an initializer. There is no "undefined" or "garbage" memory.
| Type | Zero value |
|---|---|
Numeric (int, float64, ...) |
0 |
bool |
false |
string |
"" |
| Pointer, slice, map, chan, func | nil |
| Struct | All fields zeroed |
This is why var s []int; s = append(s, 1) is valid even though s was never
explicitly initialized.
Naming conventions
- Short names for short scopes:
ifor a loop index,rfor a*Reader,sfor a string. - Longer descriptive names for package-level identifiers.
- Receivers are typically 1–2 letters:
func (b *Buffer) Write(...). - Error variables are named
Err...:var ErrNotFound = errors.New(...). - Interfaces with one method are named after the method +
er:Reader,Writer,Stringer.
Whitespace and semicolons
Go uses semicolons internally but the lexer inserts them, so you almost never type one. Two consequences:
- Opening braces must be on the same line as the keyword:
```go if x > 0 { // OK ... }
if x > 0 // COMPILE ERROR: ; inserted before { { ... } ```
- Statements are line-terminated; you can write multiple on one line with
;but it's not idiomatic.
Run the example
go run ./part1-language/examples/03_lexical