A Gentle Introduction to Go for Python Programmers



Image by Author | Ideogram

 

If you’ve been working with Python and want to add Go to your programming toolbox, you’re in the right place. This article will help you learn the fundamentals of programming with Go.

Rather than starting from zero, we’ll build on what you already know as a Python developer to help you get comfortable with Go’s syntax and concepts. Let’s get started.

🔗 Link to the code on GitHub

 

Getting Started with Go: Setup & Your First Project

 
Before writing our first lines of Go code, let’s get our environment set up. Installing Go and creating a project is relatively straightforward compared to Python’s various environment management tools.

To install Go, you can follow these steps:

  1. First, go to golang.org/dl/
  2. Download the installer for your operating system (Windows, macOS, or Linux)
  3. Run the installer, follow the installation steps
  4. Verify your installation. Run go version at your terminal

 

Note: If you’re interested in only running the code snippets in this tutorial, then use Go playground.

 

Let’s create a simple project to get you started. Go doesn’t require virtual environments like Python. Instead, it uses a single installation and manages dependencies at the project level.

Create a directory for your project:

$ mkdir hello-go
$ cd hello-go

 

Initialize a Go module:

 

This creates a go.mod file, which is similar to Python’s requirements.txt or pyproject.toml but simpler. The command argument (hello) becomes your module name.

Create a file named main.go:

package main

import "fmt"

func main() 
	fmt.Println("Hello, Go world!")

 

Run your program:

 

You should see the following output in your terminal:

 

Note: All programs in Go are made of packages and they typically start running from the main package. To focus on the concepts better, I’ll show only the relevant lines. But you can place those lines of code in  a generic .go file like this:

package main

import "fmt"

func main() 
	//YOUR CODE GOES HERE

 

1. Basic Syntax and Variables

 
Let’s start with the basic structure of a Go program:

Every Go file starts with a package declaration. The main package is special – it’s the entry point for executable programs. The import statement brings in packages you need, like fmt for formatting and printing.

Now let’s look at variable declarations:

// Explicit variable declaration with type
var name string = "Gopher"

 

In this example, we’re explicitly declaring a variable of type string. Unlike Python, Go requires you to specify types for your variables.

But you can also use the following syntax that can infer the type:

// Type inference with the := operator
age := 5

 

The := operator both declares and initializes a variable, letting Go figure out the type from the value.

Constants work similarly but use the const keyword:

// Constant declaration
const pi = 3.14159

 

In a sample variables.go file, you’ll now have:

package main

import "fmt"

func main() 
	// Explicit variable declaration with type
	var name string = "Gopher"
	// Type inference with the := operator
	age := 5
	// Constant declaration
	const pi = 3.14159

	fmt.Println(name)
	fmt.Println(age)
	fmt.Println(pi)


 

You cannot declare a variable without using it, so we just print out the values of variables here.

Go is statically typed, which is quite different from Python’s dynamic typing. This means all types are checked at compile time, helping catch errors before your program runs.

 

2. Control Structures

 
Let’s look at Go’s if statements:

// If statement
score := 85
if score >= 90 
	fmt.Println("A grade")
 else if score >= 80 
	fmt.Println("B grade")
 else 
	fmt.Println("Lower grade")

 

Output:

 

Notice there are no parentheses around the condition, but curly braces are mandatory. Remember, the condition should be a boolean expression.

Now let’s examine Go’s standard for loop:

 

This loop initializes n to 0, continues while n < 4, and increments n after each iteration.

Count: 0
Count: 1
Count: 2
Count: 3

 

Go doesn’t have a separate while loop – instead, you use for with just a condition:

// For as a while loop
sum := 1
for sum 

 

To iterate over elements in a collection, use the range keyword:

// Iterating with range
fruits := []string"apple", "banana", "cherry"
for index, fruit := range fruits 
	fmt.Println(index, fruit)


 

This outputs:

0 apple
1 banana
2 cherry

 

The range function gives both the index and value (similar to Python’s enumerate()). If you need only the value, you can use the blank identifier _:

// Using _ to ignore the index
for _, fruit := range fruits 
	fmt.Println(fruit)

 

3. Functions

 
In Go, you can declare functions with the func keyword like so:

func add(x int, y int) int 
	return x + y

 

You should define the functions outside func main() and you can call the declared functions inside the main() function.

Notice that the parameter types come after the parameter names. You specify the return type after the parameter list. When parameters share the same type, you can use a shorthand:

func subtract(x, y int) int 
	return x - y

 

One of Go’s distinctive features is the ability to return multiple values:

// Function returning multiple values
func divide(x, y float64) (float64, string) 
	if y == 0 
    	return 0, "division by zero"
	
	return x / y, ""

 

You can now call this function:

package main

import "fmt"
...

func main() 
	result, message := divide(10, 2)
	if message != "" 
		fmt.Println("Error:", message)
	 else 
		fmt.Println("Result:", result)
	


 

Output:

 

In addition, Go allows for named return values:

func calculateStats(values []int) (min, max, sum int) 
	if len(values) == 0 
		return 0, 0, 0
	

	min = values[0]
	max = values[0]
	sum = 0

	for _, v := range values 
		if v  max 
			max = v
		
		sum += v
	

	return // naked return

 

You can call the function with suitable arguments as shown:

package main

import "fmt"
...

func main() 
	values := []int5, 8, 2, 10, 3
	min, max, sum := calculateStats(values)
	fmt.Println("Min:", min)
	fmt.Println("Max:", max)
	fmt.Println("Sum:", sum)

 

Output:

 

4. Error Handling

 
Go’s approach to error handling is different from Python’s exceptions. Instead of try/except blocks, Go functions return errors that must be explicitly checked:

// Importing the errors package
import "errors"

// Function that returns an error
func divide(a, b int) (int, error) 
	if b == 0 
    	return 0, errors.New("division by zero")
	
	return a / b, nil

 

When calling a function that might return an error, you check if the error is non-nil:

package main

import (
	"errors"
	"fmt"
)

// Importing the errors package

// Function that returns an error
func divide(a, b int) (int, error) 
	if b == 0 
		return 0, errors.New("division by zero")
	
	return a / b, nil


func main() 
	// Handling the error
	result, err := divide(10, 0)
	if err != nil 
		fmt.Println("Error occurred:", err)
	 else 
		fmt.Println("Result:", result)
	


 

This raises the error as expected:

Error occurred: division by zero

 

The focus on explicit error checking helps make Go code robust and readable. It forces you to think about what should happen when something goes wrong.

 

5. Data Structures

 

Arrays

Arrays in Go have a fixed size:

	// Declaring an array and initializing it
var colors [3]string
colors[0] = "Red"
colors[1] = "Green"
colors[2] = "Blue"

 

In Go, you can also declare and initialize an array like so:

// Array literal
numbers := [5]int1, 2, 3, 4, 5

 

Slices

Slices are like Python lists – they’re dynamic arrays:

// Creating a slice
fruits := []string"Apple", "Banana", "Cherry"

 

You can add elements to a slice using append like so:

// Adding elements to a slice
fruits = append(fruits, "Date")

 

Note that append returns a new slice – it doesn’t modify the slice in place.

You can also create slices from other slices or arrays.

 

Maps

Maps are Go’s equivalent to Python dictionaries:

// Creating a map
ages := map[string]int
    "Alice": 25,
    "Bob":   30,

 

Accessing, adding, and updating values works as you’d expect:

// Working with maps
fmt.Println(ages["Alice"])  // 25
ages["Charlie"] = 22        // Add a new entry
ages["Alice"] = 26          // Update an existing entry

 

Checking if a key exists is a common operation:

// Check if a key exists
age, exists := ages["Dave"]
if exists 
    fmt.Println("Dave's age:", age)
 else 
    fmt.Println("Dave not in map")

 

Output:

 

To remove a key-value pair, use:

// Delete an entry
delete(ages, "Bob")

 

6. Concurrency with Goroutines and Channels

 
The Go runtime manages lightweight threads called Goroutines:

// Starting a goroutine
go func() 
    fmt.Println("Running in a goroutine")
()

 

The go keyword starts a new goroutine. Here we’re using an anonymous function, but you can also run named functions in goroutines.

Channels are used for communication between goroutines:

// Creating a channel
ch := make(chan string)

 

Send data to a channel:

// Sending to a channel
go func() {
    ch 

 

Receive data from a channel:

 

Here’s a more complete example that shows the usefulness of this approach:

ch := make(chan string)
// Goroutine that produces values
go func() {
    for i := 0; i 

 

The range loop will continue until the channel is closed, making it easy to process all values sent to the channel.

Received: Message 0
Received: Message 1
Received: Message 2
Received: Message 3
Received: Message 4

 

Wrapping Up

 
Go offers a compelling alternative to Python with its strong typing, compilation to native code, and excellent concurrency support. As a Python developer, you’ll find that Go’s emphasis on simplicity and readability makes it relatively easy to pick up, though you may need to adjust to explicit type declarations and a different error handling approach.

Some key takeaways:

  • Go is statically typed, compiled, and focuses on simplicity
  • Error handling in Go is explicit with returned error values
  • Go’s concurrency model with goroutines and channels is powerful and intuitive
  • The syntax is minimal compared to Python but expressive in its own way

I hope this introduction helps you get started with Go programming. Happy coding!
 
 

Bala Priya C is a developer and technical writer from India. She likes working at the intersection of math, programming, data science, and content creation. Her areas of interest and expertise include DevOps, data science, and natural language processing. She enjoys reading, writing, coding, and coffee! Currently, she’s working on learning and sharing her knowledge with the developer community by authoring tutorials, how-to guides, opinion pieces, and more. Bala also creates engaging resource overviews and coding tutorials.



Recent Articles

Related Stories

Leave A Reply

Please enter your comment!
Please enter your name here