Go is a statically typed programming language. Every variable in Golang has an associated type.

Data types classify a related set of data. They define how the data is stored in memory, what are the possible values that a variable of a particular data type can hold, and the operations that can be done on them.

Golang has several built-in data types for representing common values like numbers, booleans, strings etc. In this article, We’ll look at all these basic data types one by one and understand how they work.

## Numeric Types

Numeric types are used to represent numbers. They can be classified into Integers and Floating point types -

### 1. Integers

Integers are used to store whole numbers. Go has several built-in integer types of varying size for storing signed and unsigned integers -

#### Signed Integers

TypeSizeRange
int88 bits-128 to 127
int1616 bits-215 to 215 -1
int3232 bits-231 to 231 -1
int6464 bits-263 to 263 -1
intPlatform dependentPlatform dependent

The size of the generic `int` type is platform dependent. It is 32 bits wide on a 32-bit system and 64-bits wide on a 64-bit system.

#### Unsigned Integers

TypeSizeRange
uint88 bits0 to 255
uint1616 bits0 to 216 -1
uint3232 bits0 to 232 -1
uint6464 bits0 to 264 -1
uintPlatform dependentPlatform dependent

The size of `uint` type is platform dependent. It is 32 bits wide on a 32-bit system and 64-bits wide on a 64-bit system.

When you are working with integer values, you should always use the `int` data type unless you have a good reason to use the sized or unsigned integer types.

In Golang, you can declare octal numbers using prefix `0` and hexadecimal numbers using the prefix `0x` or `0X`. Following is a complete example of integer types -

``````package main
import "fmt"

func main() {
var myInt8 int8 = 97

/*
When you don't declare any type explicitly, the type inferred is `int`
(The default type for integers)
*/
var myInt = 1200

var myUint uint = 500

var myHexNumber = 0xFF  // Use prefix '0x' or '0X' for declaring hexadecimal numbers
var myOctalNumber = 034 // Use prefix '0' for declaring octal numbers

fmt.Printf("%d, %d, %d, %#x, %#o\n", myInt8, myInt, myUint, myHexNumber, myOctalNumber)
}``````
``````# Output
97, 1200, 500, 0xff, 034``````

#### Integer Type aliases

Golang has two additional integer types called `byte` and `rune` that are aliases for `uint8` and `int32` data types respectively -

TypeAlias For
byteuint8
runeint32

In Go, the `byte` and `rune` data types are used to distinguish characters from integer values.

Golang doesn’t have a `char` data type. It uses `byte` and `rune` to represent character values. The `byte` data type represents ASCII characters and the `rune` data type represents a more broader set of Unicode characters that are encoded in UTF-8 format.

Characters are expressed in Golang by enclosing them in single quotes like this: `'A'`.

The default type for character values is `rune`. That means, if you don’t declare a type explicitly when declaring a variable with a character value, then Go will infer the type as `rune` -

``var firstLetter = 'A' // Type inferred as `rune` (Default type for character values)``

You can create a `byte` variable by explicitly specifying the type -

``var lastLetter byte = 'Z'``

Both `byte` and `rune` data types are essentially integers. For example, a `byte` variable with value `'a'` is converted to the integer 97.

Similarly, a `rune` variable with a unicode value `'♥'` is converted to the corresponding unicode codepoint `U+2665`, where `U+` means unicode and the numbers are hexadecimal, which is essentially an integer.

``````package main
import "fmt"

func main() {
var myByte byte = 'a'
var myRune rune = '♥'

fmt.Printf("%c = %d and %c = %U\n", myByte, myByte, myRune, myRune)
}``````
``````# Output
a = 97 and ♥ = U+2665``````

In the above example, I’ve printed the variable `myByte` in character and decimal format, and the variable `myRune` in character and Unicode format.

### 2. Floating Point Types

Floating point types are used to store numbers with a decimal component (ex - 1.24, 4.50000). Go has two floating point types - `float32` and `float64`.

• `float32` occupies 32 bits in memory and stores values in single-precision floating point format.
• `float64` occupies 64 bits in memory and stores values in double-precision floating point format.

The default type for floating point values is `float64`. So when you initialize a floating point variable with an initial value without specifying a type explicitly, the compiler will infer the type as `float64` -

``var a = 9715.635   // Type inferred as `float64` (the default type for floating-point numbers)``

### Operations on Numeric Types

Go provides several operators for performing operations on numeric types -

• Arithmetic Operators: `+`, `-`, `*`, `/`, `%`

• Comparison Operators: `==`, `!=`, `<`, `>`, `<=`, `>=`

• Bitwise Operators: `&`, `|`, `^`, `<<`, `>>`

• Increment and Decrement Operators: `++`, `--`

• Assignment Operators: `+=`, `-=`, `*=`, `/=`, `%=`, `<<=`, `>>=`, `&=`, `|=`, `^=`

Here is an example demonstrating some of the above operators -

``````package main
import (
"fmt"
"math"
)
func main() {
var a, b = 4, 5
var res1 = (a + b) * (a + b)/2  // Arithmetic operations

a++ // Increment a by 1

b += 10 // Increment b by 10

var res2 = a ^ b // Bitwise XOR

var r = 3.5
var res3 = math.Pi * r * r  // Operations on floating-point type

fmt.Printf("res1 : %v, res2 : %v, res3 : %v\n", res1, res2, res3)
}``````
``````# Output
res1 : 40, res2 : 10, res3 : 38.48451000647496``````

## Booleans

Go provides a data type called `bool` to store boolean values. It can have two possible values - `true` and `false`.

``````var myBoolean = true
var anotherBoolean bool = false``````

### Operations on Boolean Types

You can use the following operators on boolean types -

Logical Operators:

• `&&` (logical conjunction, “and”)
• `||` (logical disjunction, “or”)
• `!`   (logical negation)

Equality and Inequality: `==`, `!=`

The operators `&&` and `||` follow short-circuiting rules. That means, in the expression `E1 && E2`, if `E1` evaluates to `false` then `E2` won’t be evaluated. Similarly, in the expression `E1 || E2`, if `E1` evaluates to `true` then `E2` won’t be evaluated.

Here is an example of Boolean types-

``````package main
import "fmt"

func main() {
var truth = 3 <= 5
var falsehood = 10 != 10

// Short Circuiting
var res1 = 10 > 20 && 5 == 5 // Second operand is not evaluated since first evaluates to false
var res2 = 2*2 == 4 || 10%3 == 0 // Second operand is not evaluated since first evaluates to true

fmt.Println(truth, falsehood, res1, res2)
}``````
``````# Output
true false false true``````

## Complex Numbers

Complex numbers are one of the basic types in Golang. Go has two complex types of different sizes -

• `complex64`: both real and imaginary parts are of `float32` type.
• `complex128`: both real and imaginary parts are of `float64` type.

The default type for a complex number in golang is `complex128`. You can create a complex number like this -

``var x = 5 + 7i  // Type inferred as `complex128```

Go also provides a built-in function named `complex` for creating complex numbers. If you’re creating a complex number with variables instead of literals, then you’ll need to use the `complex` function -

``````var a = 3.57
var b = 6.23

// var c = a + bi won't work. Create the complex number like this -
var c = complex(a, b)``````

Note that, both real and imaginary parts of the complex number must be of the same floating point type. If you try to create a complex number with different real and imaginary part types, then the compiler will throw an error -

``````var a float32 = 4.92
var b float64 = 7.38

/*
The Following statement Won't compile.
(Both real and imaginary parts must be of the same floating-point type)
*/
var c = complex(a, b)  // Compiler Error``````

#### Operations on complex numbers

You can perform arithmetic operations like addition, subtraction, multiplication, and division on complex numbers -

``````package main
import "fmt"

func main() {
var a = 3 + 5i
var b = 2 + 4i

var res1 = a + b
var res2 = a - b
var res3 = a * b
var res4 = a / b

fmt.Println(res1, res2, res3, res4)
}``````
``````# Output
(5+9i) (1+1i) (-14+22i) (1.3-0.1i)``````

## Strings

In Go, a string is a sequence of bytes.

Strings in Golang are declared either using double quotes as in `"Hello World"` or back ticks as in ``Hello World`` .

``````// Normal String (Can not contain newlines, and can have escape characters like `\n`, `\t` etc)
var name = "Steve Jobs"

// Raw String (Can span multiple lines. Escape characters are not interpreted)
var bio = `Steve Jobs was an American entrepreneur and inventor.
He was the CEO and co-founder of Apple Inc.```````

Double-quoted strings cannot contain newlines and they can have escape characters like `\n`, `\t` etc. In double-quoted strings, a `\n` character is replaced with a newline, and a `\t` character is replaced with a tab space, and so on.

Strings enclosed within back ticks are raw strings. They can span multiple lines. Moreover, Escape characters don’t have any special meaning in raw strings.

``````package main
import "fmt"

func main() {
var website = "\thttps://www.callicoder.com\t\n"

var siteDescription = `\t\tCalliCoder is a programming blog where you can find
practical guides and tutorials on programming languages,
web development, and desktop app development.\t\n`

fmt.Println(website, siteDescription)
}``````
``````# Output
https://www.callicoder.com
\t\tCalliCoder is a programming blog where you can find
practical guides and tutorials on programming languages,
web development, and desktop app development.\t\n``````

That’s all about Strings in this article. But there is a lot more to learn about strings which include string indexing, handling unicode characters, performing various operations like string concatenation, split, join etc. We’ll learn about them in a future article.

## Type Conversion

Golang has a strong type system. It doesn’t allow you to mix numeric types in an expression. For example, You cannot add an `int` variable to a `float64` variable or even an `int` variable to an `int64` variable. You cannot even perform an assignment between mixed types -

``````var a int64 = 4
var b int = a  // Compiler Error (Cannot use a (type in64) as type int in assignment)

var c int = 500

var result = a + c // Compiler Error (Invalid Operation: mismatched types int64 and int)``````

Unlike other statically typed languages like C, C++, and Java, Go doesn’t provide any implicit type conversion. To learn why Go is designed this way, check out the next article - Working with Constants in Golang.

All right! So we cannot add, subtract, compare or perform any kind of operation on two different types even if they are numeric. But what to do if we need to perform such operations?

Well, you’ll need to explicitly cast the variables to the target type -

``````var a int64 = 4
var b int = int(a)  // Explicit Type Conversion

var c float64 = 6.5

// Explicit Type Conversion
var result = float64(b) + c  // Works``````

The general syntax for converting a value `v` to a type `T` is `T(v)`. Here are few more examples -

``````var myInt int = 65
var myUint uint = uint(myInt)
var myFloat float64 = float64(myInt)``````

## Conclusion

That’s all folks! In this article, you learned about various basic data types provided by Golang, the operations that can be done on those types, and how to convert one type to another.

Thanks for reading. Stay tuned for more articles.

Next Article: Working with Constants in Golang

Code Samples: github.com/callicoder/golang-tutorials