youngman_ItT_00 By Nathan Youngman

This article was excerpted from the book Learn Go


An introduction to types

The text "Go" and the number 28487 are both represented with the same zeroes and ones on an x86 computer (0110111101000111). The type establishes what those bits and bytes mean. One is a string of two characters, the other is a 16-bit integer (2 bytes). Strings are used for multilingual text, and 16-bit integers are just one of numerous numeric types. Go also has a Boolean type for true and false.

A variable’s type also establishes what behavior is appropriate for it. Text can be converted to upper case and numbers can be divided. Likewise, nonsensical behavior is prevented. By using types, the Go compiler will report an error if you attempt to upper case a number or perform division on text.


The unseen types

Every variable has a type, yet Chapter 1 made no mention of types. When you don’t specify a type, the Go compiler will determine a variable’s type for you. The following three lines of code are equivalent, because the compiler will infer that countdown is a string, based on the quoted text to its right.

countdown := "Launch in T minus 10 seconds." 
var countdown = "Launch in T minus 10 seconds."
var countdown string = "Launch in T minus 10 seconds."

short declaration syntax

While it is valuable to know that countdown has a string type, it is superfluous to specify string. You, me, and the Go compiler can all infer that countdown is a string of text just by looking.

The golint tool provides hints for coding style. It discourages the clutter with the following message:

"should omit type string from declaration of var countdown; it will be inferred from the right-hand side"

It isn’t an error to specify a type, so you can if you believe it adds clarity. But as a matter of style, try to remember which types Go will infer, and rely on type inference.


Types can be inspected

If you are curious which type the Go compiler inferred, the Printf function provides the %T format verb to display a variable’s type.


Listing 1 Inspect a variable’s type: inspect.go

countdown := "Launch in T minus 10 seconds."
fmt.Printf("%T", countdown) 

Print string


experiment    Experiment: inspect.go

Navigate to the Go Playground at play.golang.org and type Listing 1 into the body of the main function.

  • Declare countdown with different values and run the program to see which types Go infers. Use a whole number, a real number, and the word true (without quotes).
  • Write down the types Go infers for the values you used. These are the most common types.

 Types have default values

In Listing 1, the countdown variable is declared and initialized with a value in one step. It is also possible to declare a variable with no value and assign a value to it later:

var countdown string

countdown = "Launch in T minus 10 seconds."
fmt.Println(countdown)

This is handy when you want to assign a value conditionally and still have the variable available outside the scope of the condition:


Listing 2 Assigning a value later: default.go

launch := false

var countdown string

if launch {
    countdown = "Launch in T minus 10 seconds."
}
fmt.Println(countdown)

If the rocket is not ready to launch, countdown will not be assigned a new value, so the default value of countdown is displayed.

In Go, each type has a default value, called the zero value. The zero value for Booleans is false. For a string, the zero value is an empty string. Unsurprisingly, the zero value for numeric types is zero.

Listing 2 declares countdown with no value, which has identical behavior to:

countdown := ""

The difference is a matter of style.

In Listing 2, the launch variable is initialized explicitly to false, even though false is the default value for Booleans. This suggests that there is an important reason for launch to be false.

On the other hand, not specifying a value for countdown hints that the real value is yet to come.


Types are static

In Go, once a variable is declared, it has a type and that type cannot be changed. This is known as static typing. Attempting to use a variable with a value of a different type will cause the Go compiler to report an error:

var greeting = "Hello Universe"
greeting = 42 

var num = 42
num = 3.14 

This is an error because greeting can only store text

This is an error because num can only store whole numbers

Another class of languages use dynamic typing instead of static typing, where each value has an associated type, and variables can hold values of any type. In those languages (JavaScript, Python, Ruby, etc.) code similar to above would execute.


note   Note

Go does have an escape hatch for situations where the type is uncertain. For example, the Println function will accept both strings and numeric types.