# Data Types

Welcome to tutorial number 4 in our Golang tutorial series.

Please read Golang tutorial part 3: Variables of this series to learn about variables.

The following are the basic data types available in Go

- bool
- Numeric Types
- int8, int16, int32, int64, int
- uint8, uint16, uint32, uint64, uint
- float32, float64
- complex64, complex128
- byte
- rune

- string

### bool

`bool`

type represents a boolean. It can either be a `true`

or `false`

value.

```
1package main
2
3import "fmt"
4
5func main() {
6 a := true
7 b := false
8 fmt.Println("a:", a, "b:", b)
9 c := a && b
10 fmt.Println("c:", c)
11 d := a || b
12 fmt.Println("d:", d)
13}
```

In the program above, a is assigned to `true`

and b is assigned a `false`

value.

`&&`

is a boolean operator which returns true when both of the operands are true.

c is assigned the value of `a && b`

. In this case `c`

is `false`

since both `a`

and `b`

are not true.

The `||`

operator returns true when either `a`

or `b`

is `true`

. In this case `d`

is `true`

since `a`

is true. We will get the following output for this program.

```
a: true b: false
c: false
d: true
```

### Signed integers

The following are the signed integer data types available in Go.

DataType | Description | Size | Range |
---|---|---|---|

int8 | 8 bit signed integers | 8 bits | -128 to 127 |

int16 | 16 bit signed integers | 16 bits | -32768 to 32767 |

int32 | 32 bit signed integers | 32 bits | -2147483648 to 2147483647 |

int64 | 64 bit signed integers | 64 bits | -9223372036854775808 to 9223372036854775807 |

int | represents 32 or 64 bit integers depending on the underlying architecture. You should generally be using int to represent integers unless there is a need to use a specific sized integer. |
32 bits in 32 bit systems and 64 bit in 64 bit systems. | -2147483648 to 2147483647 in 32 bit systems and -9223372036854775808 to 9223372036854775807 in 64 bit systems |

```
1package main
2
3import "fmt"
4
5func main() {
6 var a int = 89
7 b := 95
8 fmt.Println("value of a is", a, "and b is", b)
9}
```

The above program will print

```
value of a is 89 and b is 95
```

In the above program `a`

is of type `int`

and the type of `b`

is inferred from the value assigned to it (95).
As we have stated above, the size of *int is 32 bit in 32 bit systems and 64 bit in 64 bit systems*. Let’s go ahead and verify this claim.

The type of a variable can be printed using `%T`

format specifier in `Printf`

function. Go has a unsafe package which has a Sizeof function which returns the size of the variable in bytes. *unsafe* package should be used with care as the code using it might have portability issues, but for the purposes of this tutorial we can use it.

The following program outputs the type and size of both variables `a`

and `b`

. `%T`

is the format specifier to print the type and `%d`

is used to print the size.

```
1package main
2
3import (
4 "fmt"
5
6 "unsafe"
7)
8
9func main() {
10
11 var a = 89
12 b := 95
13 fmt.Println("value of a is", a, "and b is", b)
14 fmt.Printf("type of a is %T, size of a is %d bytes", a, unsafe.Sizeof(a)) //type and size of a
15 fmt.Printf("\ntype of b is %T, size of b is %d bytes", b, unsafe.Sizeof(b)) //type and size of b
16}
```

The above program will print the following output

```
value of a is 89 and b is 95
type of a is int, size of a is 8 bytes
type of b is int, size of b is 8 bytes
```

We can infer from the above output that `a`

and `b`

are of type `int`

and they have a size of 8 bytes(64 bits). The output will vary if you run the above program on a 32 bit system. In a 32 bit system, a and b occupy 4 bytes(32 bits).

### Unsigned integers

The Unsigned integer type as the name indicates can only be used to store positive integers. The following are the unsigned integer data types available in Go.

DataType | Description | Size | Range |
---|---|---|---|

uint8 | 8 bit unsigned integers | 8 bits | 0 to 255 |

uint16 | 16 bit unsigned integers | 16 bits | 0 to 65535 |

uint32 | 32 bit unsigned integers | 32 bits | 0 to 4294967295 |

uint64 | 64 bit unsigned integers | 64 bits | 0 to 18446744073709551615 |

uint | 32 or 64 bit unsigned integers depending on the underlying architecture | 32 bits in 32 bit systems and 64 bits in 64 bit systems | 0 to 4294967295 in 32 bit systems and 0 to 18446744073709551615 in 64 bit systems |

Unsigned integers are used in places where negative values are not applicable.

In the following program, the variables `a`

and `b`

are of type `uint`

.

```
1package main
2
3import "fmt"
4
5func main() {
6 var a uint = 60
7 var b uint = 30
8 c := a * b
9 fmt.Println("c =", c)
10 fmt.Printf("Data type of variable c is %T", c)
11}
```

The above program prints

```
1c = 1800
2Data type of variable c is uint
```

Since `a`

and `b`

are both of type `uint`

, the inferred type of `c`

is also `uint`

### Floating point types

DataType | Description |
---|---|

float32 | 32 bit floating point numbers |

float64 | 64 bit floating point numbers |

The following is a simple program to illustrate integer and floating point types

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 a, b := 5.67, 8.97
9 fmt.Printf("type of a %T b %T\n", a, b)
10 sum := a + b
11 diff := a - b
12 fmt.Printf("sum of %f and %f is %f, diff is %f\n", a, b, sum, diff)
13
14 no1, no2 := 56, 89
15 fmt.Printf("type of no1 %T no2 %T\n", no1, no2)
16 fmt.Printf("sum of %d and %d is %d, diff is %d", no1, no2, no1+no2, no1-no2)
17}
```

The type of `a`

and `b`

is inferred from the value assigned to them. In this case `a`

and `b`

are of type `float64`

. `float64`

is the default type for floating point values. We add `a`

and `b`

and assign it to a variable `sum`

. We subtract `b`

from `a`

and assign it to `diff`

. Then `sum`

and `diff`

are printed. Similar computation is done with `no1`

and `no2`

. The above program will print,

```
type of a float64 b float64
sum of 5.670000 and 8.970000 is 14.640000, diff is -3.300000
type of no1 int no2 int
sum of 56 and 89 is 145, diff is -33
```

### Complex types

DataType | Description |
---|---|

complex64 | complex numbers with float32 real and imaginary parts |

complex128 | complex numbers with float64 real and imaginary parts |

The standard library function **complex** is used to construct a complex number with real and imaginary parts. The complex function has the following definition

```
func complex(r, i FloatType) ComplexType
```

It takes a real and imaginary part as a parameter and returns a complex type. *Both the real and imaginary parts must be of the same type. ie either float32 or float64. If both the real and imaginary parts are float32, this function returns a complex value of type complex64. If both the real and imaginary parts are of type float64, this function returns a complex value of type complex128*

Complex numbers can also be created using the shorthand syntax

```
c := 6 + 7i
```

Let’s write a small program to understand complex numbers.

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 c1 := complex(5, 7)
9 c2 := 8 + 27i
10 cadd := c1 + c2
11 fmt.Println("sum:", cadd)
12 cmul := c1 * c2
13 fmt.Println("product:", cmul)
14}
```

In the above program, c1 and c2 are two complex numbers. c1 has 5 as real part and 7 as the imaginary part. c2 has real part 8 and imaginary part 27. `cadd`

is assigned the sum of c1 and c2 and `cmul`

is assigned the product of c1 and c2. This program will output

```
sum: (13+34i)
product: (-149+191i)
```

### Other numeric types

**byte** is an alias of uint8

**rune** is an alias of int32

We will discuss bytes and runes in more detail when we learn about strings.

### string type

Strings are a collection of bytes in Go. It’s alright if this definition doesn’t make any sense. For now, we can assume a string to be a collection of characters. We will learn about strings in detail in a separate strings tutorial.

Let’s write a program using strings.

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 first := "Naveen"
9 last := "Ramanathan"
10 name := first +" "+ last
11 fmt.Println("My name is",name)
12}
```

In the above program, `first`

is assigned the string `Naveen`

, `last`

is assigned the string `Ramanathan`

. Strings can be concatenated using the `+`

operator. `name`

is assigned the value of `first`

concatenated by a `space`

followed by `last`

. The above program will print

```
1My name is Naveen Ramanathan
```

as the output.

There are some more operations that can be performed on strings. We will look at those in a separate tutorial.

### Type Conversion

Go is very strict about explicit typing. There is no automatic type promotion or conversion. Let’s look at what this means with an example.

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 a := 80 //int
9 b := 91.8 //float64
10 sum := a + b //int + float64 not allowed
11 fmt.Println(sum)
12}
```

The above code is perfectly legal in C language, but in `Go`

this program won’t compile. `a`

is of type `int`

and `b`

is `float64`

. We are trying to add 2 numbers of different types which is not allowed. When you run the program, you will get the following compilation error

```
1./prog.go:10:9: invalid operation: a + b (mismatched types int and float64)
```

To fix the error, both `a`

and `b`

must be of the same type. Let’s convert `b`

to `int`

. *T(v) is the syntax to convert a value v to type T*

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 a := 80 //int
9 b := 91.8 //float64
10 sum := a + int(b) //int + float64 not allowed
11 fmt.Println(sum)
12}
```

Since `b`

is converted from `float`

to `int`

, its floating point will be truncated and hence we see `171`

as the output.

The same is the case with assignment. Explicit type conversion is required to assign a variable of one type to another. This is explained in the following program.

```
1package main
2
3import (
4 "fmt"
5)
6
7func main() {
8 i := 10
9 var j float64 = float64(i) //this statement will not work without explicit conversion
10 fmt.Println("j =", j)
11}
```

In line no. 9, `i`

is converted to `float64`

and then assigned to `j`

. When you try to assign `i`

to `j`

without any type conversion, the compiler will throw an error.

This brings us to an end of this tutorial. Please post your feedback and queries in the comments section. Please consider sharing this tutorial on twitter or LinkedIn. Have a good day.

**Next Tutorial - Constants**

**Previous Tutorial - Variables**