Go

Getting Started With Variables in Go(lang)

Harry 7 min read
Table of Contents

Go (also referred to as Golang), is a statically typed language which requires you to define the types of variables when they are initialised. Once assigned to a datatype, they cannot hold data from another type.

Variables will be a familiar topic if you're coming from another programming language. They allow you to store values, pass things around, and conditionally control logic based on inputs.

The other side of the coin are dynamically typed languages which allow you to change the type freely.

Understanding the Syntax

Let's look at a very basic example of how we can create a variable in Go to get familiar with the syntax.

package main

func main() {
	var name = "Bob"
}

Reviewing the code above, we have a very minimal Go program. And all we're doing is defining a variable name and assigning a string "Bob" to it.

We can also use the shorthand syntax := to eliminate the need for using var. The code below is exactly the same as the code above.

package main

func main() {
	name := "Harry"
}

You may notice that I haven't assigned a type to the variable. Didn't I say Go was a statically typed language? Go can infer the type of the variable by the data you assign it, so you have no need to assign the type here.

However, should you want to be explicit about it. You can pass in the data type after the name of the variable. Like so:

var name string = "Harry"

You would use this approach when you do not have an initial value and want to assign a value to the variable later on:

var name string
name = "Harry"

In a dynamically typed language, you would be allowed to reassign the value of a variable to another type. For example, if I try to put in a number (integer) after declaring a variable as a string. Go will complain and you will not be able to compile or run the program.

name := "Harry"
name = 500 // Not allowed

Another thing to note is Go expects the data type to follow the name of the variable. This can take a little getting used to if you come from another language that expects the type to precede the variable name.

Handling Numbers

Numbers can be broken up into two categories. Integers, and floating-point numbers (sometimes referred to as floats). If you are unfamiliar with the concept, integers are whole numbers with no fractional part, i.e.: 4, 6, -2, 230, 0. Whereas floating-point numbers hold a fractional value, ie.: 3.141, -582.2, 10.01.

Integers

To create a variable holding an integer, it's as simple as passing in the value at the point of variable declaration.

age := 30 // inferring type automatically
var age int = 30 // declaring variable as an integer

The above example will initialise a variable of type int. Depending on the CPU architecture, int will refer to one of the below types and will hold a number from/to the provided ranges.

  • int8: signed 8-bit integers (-128 to 127)
  • int16: signed 16-bit integers (-32768 to 32767)
  • int32: signed 32-bit integers (-2147483648 to 2147483647)
  • int64: signed 64-bit integers (-9223372036854775808 to 9223372036854775807)
  • uint8: unsigned 8-bit integers (0 to 255)
  • uint16: unsigned 16-bit integers (0 to 65535)
  • uint32: unsigned 32-bit integers (0 to 4294967295)
  • uint64: unsigned 64-bit integers (0 to 18446744073709551615)

If you're on a 64-bit operating system, int will map to int64. A 32-bit will be int32 and so forth. In most cases, leaving it as int will be okay. But if you're keen on optimisation then you have the option to manually set the size of the variable by passing in one of the above types:

var age int8 = 4

Floating-Point Numbers

Much in the same way as integers, floating-point numbers store a fractional value. In Go we can automatically createa floating-point type by initialising the variable with a fractional number.

pi := 3.141 // inferring type automatically
var pi float32 // declaring variable as float

Note that you cannot perform math between integer types and floating-point types.

You would have to define the variable with a fractional part:

a := 12.5
b := 3.0 // b := 3 would error when multiplying a by b
result := a * b

Or you could wrap the integer as another data type by casting to a specific type.

a := 12.5
b := 3
result := a * float64(b)

Handling Booleans

Boolean values can have one of two possible states: true or false. Booleans are often used for making decisions in conditional statements, controlling the flow of a program, and expressing logical concepts.

Here's a basic overview of how bool works in Go:

var isTrue bool = true
isFalse := false

Booleans can be combined and manipulated using various logical operators in Go. Common Boolean operators include:

  • && (logical AND): Returns true if both operands are true.
  • || (logical OR): Returns true if at least one operand is true.
  • ! (logical NOT): Negates a Boolean value, turning true into false and vice versa.

You will also see booleans are commonly used in conditional statements like if and switch to determine the flow of a program. For example:

if isTrue {
    // This block of code will execute because isTrue is true.
} else {
    // This block will not execute.
}

Handling Strings

A string is a data type used in computer programming to represent text or a sequence of characters.

In essence, a string is a collection of characters, which can include letters, numbers, symbols, spaces, and even special characters like newline and tabs.

To define a string, we can wrap text within quotation marks (") to store that value in the variable. This is how you would create a variable containing the phrase, "Hello, World!".

hello := "Hello, World!"

There is another another way, and that's by using backticks (`). We'll get into the differences between the two in a moment.

hello := `Hello, World!`

Based on which quotes we use, determines how the strings are interpreted. By using regular quotation marks "", special characters like newline characters are interpreted.

For example, the below will print out "Hello, World" with a newline between both words.

hello := "Hello,\nWorld"
fmt.Println(hello)
Hello world with quotes

Whereas the non-literal verison using backticks (``) will not handle special characters are simply reprint them.

hello := `Hello,\nWorld`
fmt.Println(hello)
Hello world with backticks

Handling Arrays

Arrays allow you to group together multiple values of the same type within a single variable. You must define the size alongside the type definition at initilisation as arrays in Go are fixed size.

To declare an array with 5 integers, first pass in the size followed by the type, then the values to assign into the array within curly braces.

var numbers := [5]int{1, 2, 3, 4, 5}

You can also omit the size and let Go determine the size based on the number of values passed in at initialisation.

numbers := [...]int{1,2,3,4,5}

Accessing Arrays

Elements in an array can be accessed using their zero-based index. For example, to access the first element of the numbers array:

firstNumber := numbers[0]

This behaviour changes between programming languages but it's more common to see arrays begin at 0 and Go is one example of this.

Now what if you try to access an element that is outside of the array? Or to put this another way, if our array is holding 5 elements. What happens if I try accessing the 5th element (the last element in the array)?

numbers := [...]int{1, 2, 3, 4, 5}

fmt.Println(numbers[5])

Go will refuse to run the program and we'll be unable to build a binary. Since Go knows the size of our array, it also knows when we're accessing an element that is out of bounds.

The above error can be a common error programmers make. Since arrays begin at 0 and the array has elements within it, this would mean the last element in the array is the length of the array-1.

The correct way to do this would be:

numbers := [...]int{1, 2, 3, 4, 5}
fmt.Println(numbers[4])

// Or

fmt.Println(numbers[len(numbers)-1])

Handling Slices

Slices are like arrays, but dynamically sized. This means their size can change after initialisation and are far more flexible than their array counterparts.

To see how this works in actions:

numbers := []int{1, 2, 3, 4, 5}

What sets this apart from the same example from the arrays section above, is we are omitting the size of the array within the square brackets ([]).

numbers:= []int{1, 2, 3, 4, 5} // Initialise the slice

numbers = append(numbers, 6) // Append 6 to the end of the slice ([1, 2, 3, 4, 5, 6])

fmt.Println(numbers[len(numbers)-1]) // Prints out 6

This example works on a similar example above whilst showing its compatability with arrays. We're also appending a value to the slice to we get an output of 6 instead of 5.

Handling Maps

If you're coming from another language, you may have used maps albeit under another name. Sometimes called dictionaries or hashmaps, store key => value pairs.

Jumping in with an example, here is a map containing two key value pairs.

var ages = map[string]int{"Bob": 22, "Bill": 33}

fmt.Println(ages["Bob"]) // Prints out 22

Let's break it down to the minimum:

var ages = map[key]value{}

We begin by using the keyword map to say we want to define a map. Next is the [key] which we can assign a type for the index. In most cases this tends to be a string, but doens't have to be. Then we have the value which again we pass in a type for. Finally the {} where we enter any initial data based on the structure oc the map.

Then say we want to define a map that stores people's ages against their name. We want to use the name as the key, so the key will be a string. The age will be a whole number and so we will use an int type.

var ages = map[string]int{}

And based on our map, initilise it with the values we want to store in the {string: int} format.

var ages = map[string]int{"Bob": 22, "Bill": 33}
Share
Comments
More from Harrk Blog

Harrk Blog

Programming nonsense, tutorials, and random musings about games and technology.

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Harrk Blog.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.