Your First Program

Every Go file opens with a package clause, and an executable program is package main holding a function called main.

Syntaxpackage main ... func main() { ... }

A Go program is built out of packages. A package is a group of files that belong together and share one name. Every Go file must begin with a package clause: the word package followed by that name. No file sits outside a package.

One name is special. package main means "building this produces a program you can run". Inside it there must be a function named main. A function is a named block of instructions. func main() takes no values and gives none back. It is where the program starts, and when it reaches the end the program stops.

Imports

To use code from another package you import it. import "fmt" makes the standard library's fmt package available. fmt.Println then prints one line of text. The name before the dot is the package, and the capitalised name after it is the thing inside that package you are using.

Shorthand and longhand

Several imports can be written as separate lines or as one block in brackets. They mean exactly the same thing, and the grouped block is the conventional form. gofmt sorts the imports inside each block, but it does not join separate import lines into one block; goimports, which most editors run on save, is what merges them:

// longhand
import "fmt"
import "strings"

// shorthand, same meaning
import (
	"fmt"
	"strings"
)

Files in the same directory are one package, and they can use each other's functions with no import at all.

Example

Example · go
// Every file opens with a package clause. package main builds a runnable program.
package main

// fmt is a standard library package. It holds code for formatting and printing text.
import "fmt"

// main is where the program starts. It takes nothing and gives nothing back.
func main() {
	fmt.Println("hello, world")
}

// Output:
// hello, world

When to use it

  • Start a new command line tool from an empty directory.
  • Read an unfamiliar repository and find where its program actually begins.
  • Write a throwaway program to check how a standard library function behaves.

More examples

Calling your own function

main does not have to hold all the work. Giving a piece of behaviour a name and calling it twice is the smallest useful refactor there is, and it is how every Go program past ten lines is organised.

Example · go
package main

import "fmt"

// greet takes a piece of text named name and gives back a piece of text.
// The type after the brackets, string, is what comes back.
func greet(name string) string {
	return "hello, " + name
}

func main() {
	fmt.Println(greet("world"))
	fmt.Println(greet("go"))
}

// Output:
// hello, world
// hello, go

Two files, one package

Split this into the two files the comments name, in the same directory. Both say package main, so they are one package and greet needs no import. This is also why go run . is the command to use: go run main.go would compile only that one file and fail with "undefined: greet".

Example · go
// main.go
package main

import "fmt"

func main() {
	fmt.Println(greet("world"))
}

// greet.go
package main

func greet(name string) string {
	return "hello, " + name
}

// Output:
// hello, world

Printing with placeholders

Println is the quick form for dumping values; Printf is what you use when the exact wording matters, such as a log line or a message shown to a user. Note that Printf needs its own \n, which is the most common reason output runs together on one line.

Example · go
package main

import "fmt"

func main() {
	name := "world"
	count := 2

	// Println puts spaces between the values and ends the line for you.
	fmt.Println("hello,", name)

	// Printf fills in placeholders instead: %s takes text, %d takes a whole number.
	// \n is the end of a line, which Printf does not add on its own.
	fmt.Printf("hello, %s (%d times)\n", name, count)
}

// Output:
// hello, world
// hello, world (2 times)

Discussion

  • Be the first to comment on this lesson.