Ver en Español
Variables, Data and Structures in Go
Apr 15, 2023
Updated: Jun 25, 2026

Variables, Data and Structures in Go

In this post we'll walk together through the foundations of Go: variables, data types and structures. They are the base everything else is built on, so it's worth understanding them well from the start. Let's begin.

Variables

Variables in Go are containers for storing data. A variable holds a value, which can be anything from a number to a string of text or an object. When we define a variable, we specify the variable's name, the data type it belongs to and the value assigned to it. Once defined, we can use its name to refer to it and to access its value.

There are two main kinds of variables in Go: local variables and global variables. Local variables are defined inside a function and are only available within that function. Global variables are defined outside any function and are available throughout the program.

Local variables

Local variables are those defined inside a function or block of code. For example, in the following code the variable a is a local variable and only exists inside main:

package main

import "fmt"

func main() {
	var a = 5
	fmt.Println(a)
}

// This would be a compile error: 'a' is not defined outside the function.
// Also, a Go program cannot have loose statements at package level;
// fmt.Println(a) out here is invalid on two counts.

Global variables

Global variables are variables defined outside any function or block of code. For example, in the following code the variable b is a global variable and is available throughout the file:

package main

import "fmt"

// A global variable
var b = 10

func main() {
	// The variable b is available here
	fmt.Println(b)
}

// It's also defined here
func otra() {
	fmt.Println(b)
}

Variables can also be defined as constants. Constants are values that have a fixed value and cannot be changed during the execution of the program.

Constants

Constants are values that a program cannot change during its execution. For example, in the following code PI is a constant:

const PI = 3.14159

// This will cause an error: a constant cannot be reassigned.
PI = 88

Ways to initialize variables

Variables are containers for storing values during the execution of a program. For example, in the following code the variable x is first initialized along with its type as empty, and then we assign its value.

// Declaration of the variable 'x' in Go, empty
var x int
// Assignment of the integer value 5 to the variable 'x'
x = 5

But it's also possible to declare it without the type, as long as we set its value. This is known as type inference. The two forms below are equivalent alternatives, they cannot be written together because redeclaring y in the same block would be a compile error:

// Type inference: we declare 'y' without expressing the type
var y = 10
// Equivalent form, although here expressing the type is unnecessary
var y int = 10

Assigning one variable to another

It's possible to assign the contents of one variable to another variable. This is known as pass by value or copy.

package main

import "fmt"

func main() {
	// Declaration of the variable 'x' in Go
	var x int
	// Assignment of the integer value 5 to the variable 'x'
	x = 5
	fmt.Println("Value of x: ", x)

	var obj = x
	fmt.Println("Value of obj: ", obj)

	x = 99
	// The value of obj will still be 5 even though the value of x changed to 99
	fmt.Println("Value of obj: ", obj)
}

Data types in detail

Data types in Go determine the kind of values that can be stored and manipulated within a program. Go has a variety of primitive data types, including integers, floats, strings and booleans, as well as composite data types like arrays, slices, structs and pointers. You can also define your own data types using the type keyword.

Integers

Integers are used to store whole numeric values, like 3, -2 and 0. There are several integer types, including int8, int16, int32, int64, uint8, uint16, uint32 and uint64. There are also int and uint, whose size depends on the platform (32 or 64 bits), and which are usually the default choice when you don't need a specific size.

Floats

Floating point values are used to store numeric values with decimals, like 3.14, -2.5 and 0.0. There are two floating point types: float32 and float64.

Strings

Strings are used to store sequences of characters, like "hello world". A string is a sequence of characters encoded in UTF-8.

Booleans

Booleans are used to store logical values, like true or false.

Arrays and Slices

Here's an important distinction worth getting clear from the start. An array in Go has a fixed size set at compile time: once created, you cannot add or remove elements. A slice, on the other hand, is a flexible view over the elements and can grow using append.

An array is declared by stating its length inside brackets:

// An array of 5 elements: its size is fixed
var numeros = [5]float64{5, 10, 9, 8, 7}

A slice is declared with empty brackets and can grow:

// A slice: empty brackets, its size can change
var numeros = []float64{5, 10, 9, 8, 7}
// We add an element to our slice
numeros = append(numeros, 18)

In short: if you need a fixed size collection, use an array; if you need it to grow, use a slice. In practice, slices are far more common in everyday code.

Structs

Structs are used to store a set of related variables, like the name and the price of a product, in the same place. Structs are similar to arrays, but they can hold different data types.

For example, a struct that represents a product could look like this:

type Producto struct {
	Nombre string
	Precio float64
}

And it could be used like this:

var producto Producto
producto.Nombre = "Producto 1"
producto.Precio = 100

In short, Go offers a wide variety of data types and structures to fit the needs of your program. Knowing them and using them properly will let you write more efficient and better organized programs.

A note about quotes

In Go, double and single quotes have specific and distinct uses.

Double quotes (" "): used to represent strings of text. A string in Go is an immutable sequence of bytes and can contain any data that bytes can represent. For example, "Hola Mundo" is a string. Strings delimited by double quotes can contain escaped special characters, like \n (newline) or \t (tab).

Single quotes (' '): used to represent a single character, known as a rune in Go. A rune is a data type that represents a Unicode code point. For example, 'A' is a rune that represents the letter A. Unlike strings, a rune is an integer value and occupies 4 bytes (32 bits) in Go.

Ten examples with their solutions

Calculate the sum of two numbers:

package main

import "fmt"

func main() {
	fmt.Println("Calculate the sum of two numbers:")
	var a = 5
	var b = 10
	var resultado = sumar(a, b)
	fmt.Println("The result is: ", resultado)
}

func sumar(a int, b int) int {
	var sum = a + b
	return sum
}

Calculate the product of two numbers:

package main

import "fmt"

func main() {
	fmt.Println("Calculate the product of two numbers:")
	var a = 5.0
	var b = 10.1
	var resultado = producto(a, b)
	fmt.Println("The result is: ", resultado)
}

// When using floating point numbers, the float64 type is assigned automatically
func producto(a float64, b float64) float64 {
	var sum = a * b
	return sum
}

Calculate the average of a list of numbers:

package main

import "fmt"

func main() {
	fmt.Println("Calculate the average of a list of numbers:")
	// This is a slice of numbers, that is, a collection of numbers that can grow
	var numeros = []float64{5, 10, 9, 8, 7}
	var resultado = promedio(numeros)
	fmt.Println("The result is: ", resultado)
}

func promedio(numeros []float64) float64 {
	var sum = 0.0
	for _, numero := range numeros {
		sum += numero
	}
	return sum / float64(len(numeros))
}

Calculate the factorial of a number:

func factorial(n int) int {
	if n == 0 {
		return 1
	}
	return n * factorial(n-1)
}

Calculate the area of a circle:

import "math"

func areaCirculo(radio float64) float64 {
	return math.Pi * radio * radio
}

Calculate the perimeter of a square:

func perimetroCuadrado(lado float64) float64 {
	return lado * 4
}

Calculate the volume of a sphere:

import "math"

func volumenEsfera(radio float64) float64 {
	// We use 4.0 / 3.0 to force floating point division.
	// With 4 / 3 (integers) the result would be 1 and the volume would be wrong.
	return (4.0 / 3.0) * math.Pi * radio * radio * radio
}

Calculate the area of a triangle:

func areaTriangulo(base float64, altura float64) float64 {
	return base * altura / 2
}

Calculate the hypotenuse of a right triangle:

import "math"

func hipotenusa(cateto1 float64, cateto2 float64) float64 {
	return math.Sqrt(cateto1*cateto1 + cateto2*cateto2)
}

Ask the user for two numbers and print the result on screen:

package main

import "fmt"

func ingresoDatos() {
	var a, b float64
	fmt.Println("Enter number 1: ")
	fmt.Scanln(&a)
	fmt.Println("Enter number 2: ")
	fmt.Scanln(&b)
	fmt.Println("The numbers you entered are: ", a, b)
}

Suggested exercises

Below I leave you 20 more exercises so you can practice and send the solution as a Pull request to this repository: github.com/seagomezar/goparaprincipiantes.

Note: verify that the repository link is still live before publishing.

  1. Print the length of a string.
  2. Compare two integers and show the larger one.
  3. Calculate the square of a number.
  4. Create a function to convert a string to uppercase.
  5. Create a function to convert a string to lowercase.
  6. Determine whether a string contains a given substring.
  7. Determine whether a number is even or odd.
  8. Determine whether a string is a palindrome.
  9. Increment a number by one.
  10. Determine whether a number is within a given range.
  11. Get the index of the first occurrence of a substring in a string.
  12. Get the sum of two integers.
  13. Check whether a number is divisible by another.
  14. Determine whether a string is a number.
  15. Calculate the greatest common divisor (GCD) of two numbers.
  16. Determine whether a string starts with a given substring.
  17. Get the size of an array.
  18. Get the number of unique elements in a slice.
  19. Determine whether a number is prime.
  20. Get the indices of the duplicate elements in a slice.

3-point summary

  1. Variables hold values and can be local (inside a function) or global (available throughout the program); with var you can declare them with an explicit type or let Go infer it.
  2. Go has primitive types (integers, floats, strings, booleans) and composite ones (fixed size arrays, slices that grow with append, structs and pointers).
  3. Mind the language details: constants cannot be reassigned, copying one variable to another is pass by value, and 4.0 / 3.0 is not the same as 4 / 3 because of integer division.

That's all. I hope this post is useful to you and that you can apply it to a project you have in mind. Leave me a comment if it helped, if you want to add an opinion, or if you have any questions. And remember, if you liked it, you can also share it using the social links below. Good luck!

Sebastian Gomez

Sebastian Gomez

Creador de contenido principalmente acerca de tecnología.

Leave a Reply

0 Comments

Advertisements

Related Posts

Categorias