Skip to content
Theory · Variables and types · lesson 3 of 10

Basic types

In the lesson on variables, a variable was a labeled box. Every such box has a shape. You won't fit a book into an egg carton or a saucepan into a glasses case. In Go, the shape of the box is its type.

The two variables below print the same, even though they hold values of different types:

GO
package main

import "fmt"

func main() {
    a := 3
    b := 3.0
    fmt.Println(a, b)           // 3 3
    fmt.Printf("%T %T\n", a, b) // int float64
}

A type defines which values a variable holds and which operations are allowed on it. Let's go through the program line by line:

  1. a := 3: a gets the type int because 3 is a whole number.
  2. b := 3.0: b gets the type float64 because of the dot in 3.0.
  3. fmt.Println(a, b) prints 3 3: the fractional 3.0 is printed as 3.
  4. fmt.Printf("%T %T\n", a, b) prints the types, int float64, and only here does the difference show.

From the outside the boxes look alike, but their shapes differ.

Four basic types

TypeWhat it holdsExample
inta whole number42, -7
float64a fractional number3.14, 2.0
stringtext"Go"
booltrue or falsetrue, false

Let's look at each type on its own.

int: whole numbers

int holds a whole number with no fractional part: 42, -7, 0. The compiler makes a number without a dot an int, so a := 3 is a whole-number variable.

An int holds what you count piece by piece: a quantity, a number in a list, a score. If you need a fractional variable from a whole number, you write the type explicitly: var price float64 = 3.

float64: fractional numbers

float64 holds a number with a fractional part: 3.14, 2.0. A dot makes a value fractional, even when a zero follows it: 3.0 is a float64.

A float64 holds what you measure: a price, a weight, a temperature. You have already seen its trap: fmt.Println prints 3.0 as 3, so the output does not reveal the type. That is when %T helps.

string: text

string holds text, and it is written in double quotes: "Go". Strings are joined with the same + operator as numbers: "Go" + "pher" gives "Gopher".

The type decides what an operator does. For numbers + computes a sum, and for strings it glues them together.

You will also see the type rune: an integer that Go uses for one character of a string. It is written in single quotes, and the common mistake at the end of the lesson is about it.

bool: true or false

A bool has only two values: true and false. It holds a yes-or-no answer: whether an order is ready, whether the sound is on.

In Go, a bool is not a number. The line var ok bool = 1 does not compile: cannot use 1 (untyped int constant) as bool value in variable declaration.

The type is chosen once

A variable's type is chosen once, at the declaration, and does not change afterward. After a := 3, the variable a holds only whole numbers.

The assignment a = 2.5 does not compile: cannot use 2.5 (untyped float constant) as int value in assignment (truncated). The word truncated means the fractional part would be lost, and the compiler does not allow that.

Here the box picture stops working. You can try to cram something foreign into a real box, and sometimes it even fits. In Go that never works: the compiler checks the shape of every box before the program runs.

Formatted output

fmt.Printf prints text by a template—a format string. Each % sign followed by a letter in the template is replaced by the next argument. Here are the parts of a template from this lesson:

  • %v prints a value the same way fmt.Println does;
  • %T prints the value's type;
  • \n ends the line: unlike Println, Printf does not do that by itself.

%T helps when it is unclear which type the compiler took from a value.

GO
name := "Go"
ready := true
fmt.Printf("%v %v\n", name, ready) // Go true
fmt.Printf("%T %T\n", name, ready) // string bool

Let's go through the example line by line:

  1. name := "Go" is a string, because the value is in double quotes.
  2. ready := true is a value of type bool.
  3. The first Printf puts the values of name and ready in place of the two %v signs and prints Go true.
  4. The second Printf puts in their types and prints string bool.

Each line of output ends with the line break from \n.

Common mistake

A string is written in single quotes, as in some other languages:

GO
s := 'Go' // ✗
fmt.Println(s)
TEXT
more than one character in rune literal

In Go, single quotes hold one character—a value of type rune, not a string. Text goes in double quotes: s := "Go".

Key points

  • A type defines which values a variable holds and which operations are allowed on it; it does not change after the declaration.
  • The basic types are int, float64, string and bool; 3 gives an int, and 3.0 gives a float64.
  • fmt.Printf prints by a template: %v for the value, %T for the type, and \n ends the line.
  • Strings go in double quotes, while single quotes hold one character of type rune.

Subscribe to take the course

The course is free. Sign in with Telegram and subscribe to the channel to open every lesson.

Sign in another way