tipos-datos-basicos-go

Basic Data Types in Go and Explicit Conversions

  • 5 min

A data type in Go is the rule that indicates what values a variable can store and what operations we can perform with it.

We already know how to declare variables, but… what can we store in them?

Go is a statically and strongly typed language. This means two things:

  1. Static: The compiler needs to know the type of each variable before compiling.
  2. Strong: The compiler will not perform implicit conversions for you. You cannot add a number and a text without explicitly telling it how to do it.

Let’s look at the basic predeclared types with which we will build everything else.

Integers

In Go, integers are divided into two families: signed (int) and unsigned (uint).

Unlike languages like JavaScript (which only has Number for everything), in Go we have precise control over the memory size of our numbers.

Architecture-dependent types

These are the ones we will use 90% of the time.

  • int: 32 or 64 bits depending on the architecture we compile for.
  • uint: same size as int, but represents unsigned numbers, including zero.

Although on your machine int is 64 bits, for Go int and int64 are different types. You cannot assign them directly without a conversion.

Fixed-size types

If you need to save memory or interact with hardware/binary protocols, you will use these:

TypeDescriptionApproximate Range
int88 bits-128 to 127
int1616 bits-32768 to 32767
int3232 bits-2 billion to 2 billion
int6464 bits−9.22 × 10¹⁸ to 9.22 × 10¹⁸
uint88 bits (unsigned)0 to 255

Important aliases: byte and rune

In Go you will very often see two types that are actually aliases for integers, but are used with a semantic intention:

  • byte: An alias for uint8. Used to represent raw binary data or ASCII characters.
  • rune: An alias for int32. Used to represent a Unicode Code Point.
var a int = 10
var b uint8 = 255
var c rune = 'Ñ' // A rune is defined with single quotes
Copied!

In Go there is no char type. We use rune to represent a Unicode code point, which can occupy more than one byte in UTF-8. A visual character can be made up of several runes, something common in compound emojis.

Floating Point Numbers

For numbers with decimals, Go simplifies things and offers us two options under the IEEE-754 standard:

  • float32: Single precision.
  • float64: Double precision.
var pi float32 = 3.14
var euler float64 = 2.7182818284
Copied!

Which one to use?

By default, Go infers float64 when you write a decimal (num := 10.5). We recommend always using float64 unless you have a very specific memory constraint (such as in 3D graphics), since float32 accumulates rounding errors very quickly.

Booleans

The bool type is the simplest. It can only be true or false.

The important thing here is that Go does not allow implicit conversions.

  • In C or C++, 0 is false and 1 is true.
  • In Go, 0 is a number and false is a boolean. They don’t mix.
var active bool = true

// if 1 { ... }  <-- ERROR: "non-bool used as if condition"
// if active { ... } <-- CORRECT
Copied!

Strings

Internally, a string in Go is an immutable sequence of bytes. It can contain arbitrary bytes; by convention we usually store UTF-8 text, and source code literals are written with that encoding.

Declaration

We can use double quotes or backticks:

// Normal string (interprets escape characters like \n)
greeting := "Hello\nWorld"

// Raw String Literal (ignores escapes, allows multiline)
html := `
<html>
    <body>Hello</body>
</html>
`
Copied!

Immutability

In Go, you cannot modify a string once created.

s := "Cat"
s[0] = 'R' // ERROR: cannot assign to s[0]
Copied!

If you want to change a string, you have to create a new one or convert it to a slice of rune or byte, modify it, and convert it back.

Review of Zero Values

As mentioned in the previous article, Go guarantees that every variable has an initial value. This is important for memory safety. Here is the reference table for basic types:

TypeZero Value
Integers, float32, float64, byte, rune0
boolfalse
string"" (empty string, NOT nil)

It is important to note that an empty string has length 0, but it is not nil.

Type Conversions

Go does not implicitly convert between different numeric types.

If you want to add an int and a float64, you have to convert one of them explicitly. The syntax is Type(value).

package main

import "fmt"

func main() {
    var integer int = 42
    var decimal float64 = 55.5

    // sum := integer + decimal // ERROR: mismatched types int and float64

    // Option A: Everything to float
    sum := float64(integer) + decimal

    // Option B: Everything to int (losing decimals)
    intSum := integer + int(decimal)

    fmt.Println(sum)       // 97.5
    fmt.Println(intSum)    // 97
}
Copied!

This may seem verbose at first, but it makes the conversion visible. It does not in itself prevent precision loss, truncation, or overflow: before converting we must check that the value fits in the destination type.