Introduction to Go for Python Programmers
By: Naveen Venkatesan
Tags: Golang, Python, Go, Programming, Data Science

I’ve recently heard a lot of buzz about proramming in Go and it piqued my curiousity. Proponents of Go laud it’s simplicity, concurrency, and performance — having basically been solely a Python programmer for the last few years, I wanted to try to get started with Go myself. Through learning some of the basics, I found it easiest to try find direct mappings between Python and the equivalent operation in Go. Here is just a small introduction to get started with Go yourself.

Installation

To install Go (or golang), you can either visit their website, or use Homebrew, where it is as simple as:

brew install go

That was easy! Let’s write our first Go program.

Setting up our Go program

Let’s start with some basic boilerplate for our Go programs. We can create a folder called go_tutorial where all of our code will live. Let’s start with making a file called main.go for our first code snippet. At the top of our file, we have a package definition. Since Go is compiled, the entry point for our program will be in the main() function of the main package. So, we will have something like this:

// main package

package main // main() function

func main() {

}

The other thing we need is package imports. For example, to print text to the terminal screen (as we will do in the first example), we must import a package called fmt . After adding package imports, our code will look like this:

// main package

package main // package imports

import "fmt" // main() function

func main() {

}

Compiling and Running Our Program

To run our program, we have a couple of options. Since Go is a compiled language, there is a compilation step prior to us being able to run our program. If we want both of these steps to occur with one command, we can use go run :

> go run main.go

Of course we will get no output, since our main() function is currently empty. Another method of running our program is to use go build to create a binary file that we can then execute. If we supply go build without a filename, our binary will be the name of the overall package which is go_tutorial in our case. If we pass the filename main.go to go build , we will get a binary file called main :

# With no filename

> go build

> ./go_tutorial # With filename

> go build main.go

> ./main

Note that running go run skips the step of saving a binary file and directly runs the program.

Okay, let’s start writing our programs!

Printing Text

To print text to the screen, we use a function from the fmt package called Println() . Notice that the function has a capitalized first letter — in Go, functions that are exposed from packages (called exported functions) must begin with a capital letter.

package main import "fmt" func main() {

fmt.Println("Go!")

}

Let’s run our program:

> go build

> ./go_tutorial

Go!

Variable Declarations

Unlike Python, Go is a statically typed language, so the variables must be explicitly declared. For example, to declare a variable a with type integer, we use the following:

var a int

The variable a is now fixed to type integer. If we try to reassign it to another variable type, we will get an error at compile-time:

func main() {

var a int

a = 5

fmt.Println(a)

a = "hi"

} > go run main.go

# command-line-arguments

./main.go:9:4: cannot use "hi" (type untyped string) as type int in assignment

When we tried to reassign the a from 5 to hi , we get an error during compilation that says we cannot use a string as an integer.

We can do the variable declaration and assignment in the same line as well, and Go will infer the type:

func main() {

var a = "Go!"

fmt.Println(a)

} > go run main.go

Go!

Now, there’s an even shorter way of doing this — we can use the operator := to also do the declaration and assignment in the same line.

func main() {

var a := "Go!"

fmt.Println(a)

} > go run main.go

Go!

Lists

The data structure most similar to Python lists in Go is a slice. Slices in Go are an abstraction to the array data type that allow for more useful manipulation functions. We can create an empty integer slice as follows:

func main() {

var list []int

fmt.Println(list)

} > go run main.go

[]

We can initialize our slice with the := operator — additionally we can index our slices exactly as we would do in Python.

func main() {

list := []int{1, 2, 3, 4, 5}

fmt.Println(list)

fmt.Println(list[2])

} > go run main.go

[1, 2, 3, 4, 5]

3

Just as with Python lists, we can append items to our slices:

func main() {

list := []int{1, 2, 3}

fmt.Println(list)

list = append(a, 100, 200)

fmt.Println(list)

} > go run main.go

[1, 2, 3]

[1, 2, 3, 100, 200]

Dictionaries

To achieve similar behavior to Python dictionaries, we can use Go maps, which are data structures that also map key-value pairs. The map declaration is of the form map[key type]value type , so to create an empty map with keys of type string and values of type int , we use the following:

func main() {

dictionary := map[string]int{}

fmt.Println(dictionary)

} > go run main.go

map[]

Adding key-value pairs to our map is exactly the same as in Python

func main() {

dictionary := map[string]int{}

dictionary["a"] = 1

dictionary["b"] = 2

dictionary["z"] = 26

fmt.Println(dictionary)

fmt.Println(dictionary["b"])

} > go run main.go

map[a:1 b:2 z:26]

2

Loops

In Go, there is only one loop — the for loop. We can adapt the syntax of the for loop to behave like other loop constructions in Python, like while loops.

To create a for loop with a specified number of iterations:

func main() {

for i := 1; i <= 5; i++ {

fmt.Println(i)

}

} > go run main.go

1

2

3

4

5

To loop until a condition is met (like a while loop), we do the following, where i++ is the increment operation, like i += 1 in Python.

func main() {

i := 1

for i <= 5 {

fmt.Println(i)

i++

}

} > go run main.go

1

2

3

4

5

Finally, if we wanted to create an infinite loop until a condition is met (like while True ), we can do the following:

func main() {

for {

fmt.Println("Infinite Loop!")

break

}

fmt.Println("Loop ended")

} > go run main.go

Infinite Loop!

Loop ended

Conditional Logic

If/else statements operate largely the same in Go as they do in Python, with the only exception being explicitly using else if instead of elif in Python.

func main() {

for i := 1; i <= 10; i++ {

if i % 2 == 0 {

fmt.Println("Even")

} else {

fmt.Println("Odd")

}

}

} > go run main.go

Odd

Even

Odd

Even

Odd

Even

Odd

Even

Odd

Even

Functions

Finally, we can declare functions and use them in our main() function as well. This works very similarly to functions in Python, but since Go is statically typed, you must declare the input and return types of your function, like this:

func myFunction (variableName type) returnType

So if we wrote a function to calculate the factorial of a number, we could do as follows. We can also call our factorial function from main() :

func main() {

fmt.Println(factorial(3))

fmt.Println(factorial(6))

} func factorial(n int) int {

if n < 2 {

return 1

}

out := 1

for n > 0 {

out *= n

n--

}

return out

} > go run main.go

6

720

Final Remarks

I hope you enjoyed this article and this was enough to get you started on your Go journey! One of my favorite resources is Go By Example — we have only scratched the surface here but you can learn about some of the other nuances of the language by going there.

You can see some of my work at my personal GitHub page. I appreciate any feedback, and you can find me on Twitter and connect with me on LinkedIn for more updates and articles.