Your First Go Program

Go · Lesson 3 of 32 7 min read Updated

Every programmer starts with a small program that prints a message. In Go, that small program already teaches you the most important building blocks: packages, imports and the main function.

In this lesson you will write a program line by line, run it with go run, build a real executable with go build, and learn the few strict syntax rules that surprise beginners.

The program, line by line

Make a folder called shop, run go mod init example.com/shop inside it, and create a file main.go:

Go
// Command shop prints a welcome message for a small store.
package main

import "fmt"

func main() {
	fmt.Println("Welcome to Sharma General Store, Rohtak")
	fmt.Println("Open daily from 9 am to 9 pm")
}

Run it from inside the folder:

Terminal
go run .
Output
Welcome to Sharma General Store, Rohtak
Open daily from 9 am to 9 pm

Here is what each part does:

  • // Command shop ... is a comment. Go ignores everything after // on that line. A comment just above package main describes the whole program.
  • package main says this file belongs to the main package. Every Go file belongs to exactly one package, and main is special: it builds into a runnable program.
  • import "fmt" loads the standard fmt (format) package so you can print.
  • func main() { ... } defines the main function. When the program starts, Go runs main, and when main returns, the program ends.
  • fmt.Println(...) calls the Println function from the fmt package. The capital P matters: only names that start with a capital letter can be used from outside their package.

Printing in three ways

The fmt package has three printing functions you will use all the time:

Go
package main

import "fmt"

func main() {
	fmt.Print("Tea: ", 15, "\n")
	fmt.Println("Samosa:", 20, "rupees")
	fmt.Printf("%s costs ₹%d\n", "Vada pav", 25)
}
Output
Tea: 15
Samosa: 20 rupees
Vada pav costs ₹25
  • Print writes its arguments as they are. It adds a space between two arguments only when neither of them is a string, so here no spaces are added, and you must add the newline "\n" yourself.
  • Println always puts a space between arguments and ends with a newline. It is the easiest to use.
  • Printf takes a format string with verbs such as %s (a string) and %d (a whole number), and fills them with the remaining arguments in order. It does not add a newline, so end the format with \n.

You will learn every common verb in Printing & Formatting with fmt.

Importing several packages

When you need more than one package, group the imports in brackets, one per line. Here the program also uses the standard strings package:

Go
package main

import (
	"fmt"
	"strings"
)

func main() {
	city := "jaipur"
	fmt.Println(strings.ToUpper(city))
	fmt.Println(strings.Repeat("=", 10))
}
Output
JAIPUR
==========

city := "jaipur" creates a variable (you will study variables in the next lessons). strings.ToUpper returns an upper-case copy, and strings.Repeat repeats a string a given number of times.

Building an executable

go run compiles the program into a temporary folder and runs it. To get a program you can copy to another computer, use go build:

Terminal
go build
./shop
Output
Welcome to Sharma General Store, Rohtak
Open daily from 9 am to 9 pm

go build creates an executable named after the last part of the module path: shop on Linux and macOS, shop.exe on Windows (run it with .\shop.exe in PowerShell). The file contains everything it needs, so the other computer does not need Go installed, as long as it has the same operating system. Use go build -o store.exe to pick a different name.

Go's strict rules

Go refuses to compile some code that other languages allow. These rules feel strict at first but they keep Go code clean.

Unused imports and variables are errors. If you import "os" and never use it, the build stops:

Go
package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Println("hello")
}
Output
# example.com/shop
./main.go:5:2: "os" imported and not used

The numbers 5:2 mean line 5, column 2. Delete the import (your editor's Go extension does this for you on save) and it compiles. On Windows the path is shown as .\main.go.

The opening brace stays on the same line. Go adds semicolons automatically at the end of certain lines. If you put { on its own line after func main(), a semicolon is inserted after main() and you get a syntax error. Always write func main() {.

Formatting is standard. Run gofmt (or go fmt) and every Go file is laid out the same way: tabs for indentation, fixed spacing. Nobody argues about style in Go teams.

Comments

Go has two comment styles. // comments to the end of the line and is the one you will use almost always. /* ... */ can span several lines and is mostly used to disable a block of code for a moment.

Go
// price is in rupees, GST not included.
price := 499

/*
fmt.Println("debug:", price)
fmt.Println("this block is switched off")
*/

A comment directly above a function, type or package, starting with its name, is a doc comment. Tools like go doc and pkg.go.dev show it as documentation.

Common mistakes

  • Wrong package name. A file with package shop instead of package main builds as a library, and go run says the package is not a main package.
  • Lower-case println vs fmt.Println. Go has a built-in println that writes to standard error and is meant for debugging the runtime. Use fmt.Println in real programs.
  • Forgetting \n with Printf. Two Printf calls without \n print on the same line.

Key points

  • A runnable Go program has package main, imports, and a func main() where execution starts.
  • fmt.Println adds spaces and a newline; fmt.Print and fmt.Printf do not add a newline.
  • go run . compiles and runs; go build creates a standalone executable.
  • Unused imports and unused variables are compile errors, not warnings.
  • The opening { must be on the same line, and gofmt decides the layout.

Exercise

Write a program for a cricket coaching centre in Pune. It should print the centre's name, then use Printf to print a line like Batch: Morning, Fee: ₹1500 per month (with the batch name and fee passed as arguments). Add a comment at the top that describes the program, then build it with go build.

Show solution
Go
// Command academy prints details of a cricket coaching batch.
package main

import "fmt"

func main() {
	fmt.Println("Deccan Cricket Academy, Pune")
	fmt.Printf("Batch: %s, Fee: ₹%d per month\n", "Morning", 1500)
}
Output
Deccan Cricket Academy, Pune
Batch: Morning, Fee: ₹1500 per month

%s is filled with the string "Morning" and %d with the number 1500. Running go build in the folder creates an executable named after your module.

Quick Quiz

1. What happens if a Go file imports a package that it never uses?

2. Which function always adds a newline at the end?

3. What does go build produce for a main package?

4. Why must { stay on the same line as func main()?

Learn Go with a mentor

Free lessons get you started. Our Programming & Software Development training adds real projects and code reviews from working developers.

  • Project-based learning
  • Mentor code reviews
  • Free counselling call