Your First Go Program
Values, Types, and Functions
Goal
By the end of this lesson, you can store values in variables, choose the right type, and write functions that take values and return results. You write the first real piece of Tasker: a function that prints one task as a line of text.
What you will learn
- Go's basic types:
int,float64,string, andbool - Three ways to create a variable, and when to use each one
- Zero values, which Go gives every variable that has no value yet
- Constants
- Functions with parameters, return values, and more than one return value
- The
value, errpattern you see everywhere in Go
Why this matters
A task in Tasker has an ID (a number), a title (text), and a status (done or not done). To work with tasks, you need types to store these values and functions to work with them.
Step 1: Create the task package
In your hello project, create a folder named task and a file task/task.go:
package task
import "fmt"
// MaxTitleLength is the longest title a task can have.
const MaxTitleLength = 50
// Format returns one line that describes a task.
func Format(id int, title string, done bool) string {
status := "[ ]"
if done {
status = "[x]"
}
return fmt.Sprintf("%d. %s %s", id, status, title)
}
Replace main.go with this:
package main
import (
"fmt"
"hello/task"
)
func main() {
var title string = "Write lesson 1.3"
done := false
id := 1
fmt.Println(task.Format(id, title, done))
fmt.Println(task.Format(2, "Install Go", true))
}
Run it:
go run .
Output:
1. [ ] Write lesson 1.3
2. [x] Install Go
You can delete the greeting folder and footer.go from Lesson 1.2, or keep them. They do not affect this lesson.
Step 2: Understand the basic types
Every value in Go has a type. The type decides what values are allowed and what you can do with them.
| Type | Holds | Example |
|---|---|---|
int | whole numbers | 1, -20, 135 |
float64 | numbers with a decimal part | 2.5, 0.75 |
string | text | "Install Go" |
bool | true or false | done |
Go is statically typed. Each variable has one type, and it never changes. The compiler checks types before the program runs.
Step 3: Three ways to create a variable
Look at main again. It creates variables in two ways.
1. var with a type and a value
var title string = "Write lesson 1.3"
2. Short declaration with :=
done := false
id := 1
Go looks at the value and chooses the type. false is a bool, so done is a bool. 1 is a whole number, so id is an int. This is called type inference.
3. var with a type and no value
var count int
Use them like this:
- Inside functions, use
:=most of the time. It is short and clear. - Use
var name Typewhen you want a variable to start empty. - Outside functions (at the package level), you must use
var. The:=form only works inside functions.
Step 4: Zero values
A variable with no value is never "empty" or "undefined" in Go. It gets a zero value. Add this function to main.go:
func zero() {
var count int
var price float64
var name string
var ready bool
fmt.Printf("%d %v %q %t\n", count, price, name, ready)
}
Call zero() at the start of main and run the program. The first line of output is:
0 0 "" false
| Type | Zero value |
|---|---|
int, float64 | 0 |
string | "" (empty text) |
bool | false |
Zero values remove a whole group of bugs. A variable always holds a valid value of its type.
Step 5: Constants
Look at this line in task.go:
const MaxTitleLength = 50
A constant is a value that never changes. The compiler stops you if you try to change it. Use constants for fixed values such as limits and default settings. You use MaxTitleLength in the exercises.
Step 6: How a function is built
func Format(id int, title string, done bool) string {
funcstarts a function.Formatis the name. It starts with a capital letter, so other packages can use it.(id int, title string, done bool)are the parameters. Each one has a name and a type. The name comes first.stringafter the parentheses is the return type.returnsends a value back to the caller.
fmt.Sprintf works like fmt.Printf, but it does not print. It returns the formatted text as a string. The %d verb inserts a whole number, and %s inserts a string.
Step 7: Return more than one value
A Go function can return several values. Add this to task.go:
// SplitMinutes turns a number of minutes into hours and minutes.
func SplitMinutes(total int) (int, int) {
hours := total / 60
minutes := total % 60
return hours, minutes
}
Use it in main:
hours, minutes := task.SplitMinutes(135)
fmt.Printf("Estimate: %d h %d min\n", hours, minutes)
Output:
Estimate: 2 h 15 min
When / divides two int values, the result is a whole number: 135 / 60 is 2. The % operator gives the remainder: 135 % 60 is 15.
If you only need one of the results, use _ (the blank identifier) for the one you do not need:
_, onlyMinutes := task.SplitMinutes(45)
fmt.Println("Minutes only:", onlyMinutes)
Step 8: The value, err pattern
Many Go functions return two values: a result and an error. Add "strconv" to your imports, then add this to main:
number, err := strconv.Atoi("42")
fmt.Println(number, err)
number, err = strconv.Atoi("forty-two")
fmt.Println(number, err)
Output:
42 <nil>
0 strconv.Atoi: parsing "forty-two": invalid syntax
strconv.Atoi turns text into an int. It can fail, so it returns an error as the second value.
- If it succeeds,
errisnil.nilmeans "no value", so here it means "no error". - If it fails,
errdescribes the problem, and the number is the zero value0.
The second time, the code uses = and not :=. The variables already exist, so it only assigns new values to them.
You use this pattern in almost every Go program. In Module 2, you learn how to handle errors properly.
Why it works: Go checks types and usage before running
Try these two mistakes.
Mixing types:
var a int = 10
var b float64 = 2.5
result := a * b
Go refuses to compile it:
invalid operation: a * b (mismatched types int and float64)
Go never converts types automatically. You must convert them yourself, for example with float64(a) * b.
An unused variable:
x := 5
If x is never used, Go refuses to compile it:
declared and not used: x
Both rules can feel strict at first. They catch real bugs early, before your program reaches users.
Exercises
- Fix the type mix. Write the
a * bexample and fix it withfloat64(a). Print the result. - Check the title length. Write a function
ValidTitle(title string) boolin thetaskpackage. It returnstrueiflen(title)is greater than 0 and not greater thanMaxTitleLength. Test it with three titles. - Return two values. Write
Stats(done int, total int) (int, float64). It returns the number of open tasks and the percentage of tasks that are done. Hint: convert tofloat64before you divide. - Parse an ID. Use
strconv.Atoion"7","-3", and"abc". Print the number and the error each time. - Zero value check. Without running the code, write down what
var total float64andvar label stringhold. Then print them to check your answer.
Checkpoint
You are ready for the next lesson if you can:
- Name Go's four basic types and give an example value for each
- Explain when to use
:=and when to usevar - Say the zero value for
int,string, andbool - Write a function that returns two values, and ignore one of them with
_ - Explain what
nilmeans invalue, errcode
