March 2, 2018

Go Lang Data Types Cheatsheet

I see the value of learning and practicing new programming languages. Although the value is when the new language introduces the different paradigm than the languages you already know, and change/challenge they way you think or program. Also the important aspect is the market share for the language, i.e. whether there is the demand on the market for such skills.

In that regards the two languages I focus on apart from the main language (which is Java) which I use for day to day development these are: Go and Clojure.

I think you will agree if you are familiar with these languages that they bring new paradigms to the area of the programming languages. Well, yes both of them have inspiration of the languages existed before, but if you are young enough (as I am) to not catch them, the ideas in these language then feel new. Also these languages have a few interesting ideas by itself, which other languages didn't have.

I use Clojure these days mostly for solving puzzles on the CodinGame. And Go for writing various CLI utilities for the projects I am working on. Many of those utilities are very much project specific, so not possible to open source them or share. But some of the ideas are, and currently I implement some of them in the vmx tool (which I will write its own post about).

On the radar languages which also look interesting and have some demand on the market are Rust and Racket. I am planning to have some look into Racket this year. No plans so far regards Rust.

And yes, because my main work is still with the Java language, I keep my skills up to date in this area, while I think it is equally important to look around, and extend your professional competencies, and become familiar with new ideas and techniques which even if taken from the different languages, could improve writing the code in Java (or your main language at work).

So here below is the summary of the Go data types I came with. I hope it is useful.

Go Data Types Cheatsheet

Also available as preview, as well as download-able as PDF.

Data type Zero value nil assignable? (and so also could be compared against nil) Comparable? ==
(can be used as the key in the map)
Reference Type?
(pass by "reference" [1])
Declaration Initialization %v value in fmt

1. Basic data types

float32, float64)
0 No Yes No var x int x := 10 10
string "" No Yes No var s string s := "go" go
bool false No Yes No var b bool b := true true

2. Composite types

2.1. Aggregate types

(fixed size)
Zero value of all it elements
(len() returns the size of the array declared).
So can be used immediately after declaration without prior initialization
No Yes
(when array type is comparable)
No var a [3]int a := [3]int{10, 20, 30}
a := [...]int{10, 20, 30}
a := [...]{99: -1} (which will create the array of 100 elements, with last one initialized to -1, while the rest to their zero value, 0 in the case of the int-s) [2]
[10 20 30]
[0 0 0] for zero value
(fixed size)
Zero value of all it fields.
So can be used immediately after declaration without prior initialization
No Yes
(when all fields are comparable)
No type point struct {
x, y int
label string
visited bool
var p point
p := point{10, 20, "p", true}
or partially initialize only relevant fields
p := point{y: 20, visited: true}
or the special case when the struct is part of the map (and so the type can be omitted), i.e.:
m := map[string]point{
"p": {10, 20, "p", true},
{10 20 p true}
{0 0 false} for zero value

2.2. Reference types

(len() returns 0).
Must be initialized before the use
Yes No
(only legal comparison is with nil)
Yes var a []int a := []int{10, 20, 30}
a := make([]int, 0, 10)
If the slice is initialized with make and the length is set, i.e.
a := make([]int, 3, 10)
then len(a) will return that length, i.e. 3
[10, 20, 30]
[] for zero value (even though the zero value is nil)
[0 0 0] when length was provided for the make
(the key must be comparable using ==)
(len() returns 0).
Must be initialized before the use
Yes No
(only legal comparison is with nil)
Yes var m map[string]int m := make(map[string]int)
m := map[string]int{}
m := map[string]int{"a": 1, "b": 2}
[]map (for empty or nil map)
map[a: 1 b: 2]
pointer nil Yes Yes
(point to the same variable or both are nil)
Yes var p *int p := &x
p := new(int)
(although rarely used, also in this form new() creates the new address, so those pointers are always different, i.e. == returns false)
0xc420074068 (address pointer points to)
chan nil Yes Yes
(reference to the same channel data structure or nil)
Yes var c chan int c := make(chan int)
for unbuffered channel
c := make(chan int, 5)
for buffered channel
0xc42001e180 (address of the channel)
func nil Yes No
(only legal comparison is with nil)
var f func(int) int f := func(x int) int {
return x + 1
} // function value
or normally declared function
func inc(x int) int {
return x + 1
f := inc
0x48b500 (address of the defined function)

3. Interface type

(abstract type)
nil Yes No (only legal comparison is with nil) [4]
No var any interface{} any := 5
any := false
any := "string"
// etc. as you can assign value of any type to the interface{} type
the %v of the underlying type

4. Bonus

(is actually a struct, so everything about struct applies here)
Empty buffer ready to use

var b bytes.Buffer
// A Buffer needs no initialization, ready to use

(added in Go 1.10)
Empty builder ready to use

var b strings.Builder
// A Builder needs no initialization, ready to use

[1] Variables of these types are passed by value, as everything in the Go, although because they are “reference” types, which mean they hold the pointer (reference) to the underlying data structure, so it means that the pointer gets copied (i.e. alias is created), which allows to make the modifications to the underlying data structure pointer points (references) to.

[2] Another interesting example (taken from The Go Programming Language book):

type Currency int 
const ( 
    USD Currency = iota 
symbol := [...]string{USD: “$”, EUR: “€”, “GBP”: “£”, “RMB”: “¥”}"

[3] It said that the func is the reference type, and mentions it is possible to affect the original function, although it is not clear how. Any ideas?

[4] Although it is possible to compare interfaces with each other, it might fail at runtime when interface type (dynamic types are the same) represents the non comparable type, then it fails with panic. So compare interface values only if you are certain they contain dynamic values of comparable types.

I might have possibly missed some cases, but I believe the most common cases were covered. Will keep the table updated when new techniques are learnt or discovered in the process of practicing Go.

If you think there is something worth to add or missing, please, share this in the comments, I will appreciate, and then update the cheatsheet accordingly!

Thanks, guys!

Tags: development go