Fundamentals of GO Language

Gayuru Premaratne
Technoid Community
Published in
7 min readJun 22, 2023

Go, also known as Golang, is a statically typed, compiled programming language created by Google in 2009. Go is designed to be simple, fast, and efficient, making it an ideal choice for developing web services, cloud-native applications, and other systems-level software. In this blog post, we’ll be exploring the fundamentals of Go programming language and why you should consider using it for your next project.

Syntax

The syntax of Go is straightforward and easy to learn, even for those who have never coded before. Go follows a C-style syntax, which makes it easier for developers who have experience with C, C++, or Java to pick up quickly.

Package declaration: Every Go program must belong to a package. The first line of a Go program is the package declaration, which specifies the name of the package the program belongs to. The most common package is main, which is used for executable programs.

Imports: Go allows you to use code from other packages by importing them. The import statement is used to import packages into your program. In the following example, the fmt package is imported to allow the use of the Println function:

Control Flow: Go supports several control flow statements, including if, for, switch, and goto. In the following example, an if statement is used to determine if a number is positive or negative:

func sign(x int) string {
if x > 0 {
return "positive"
} else {
return "negative"
}
}

Pointers: Pointers are variables that store the memory address of another variable. In Go, you can declare a pointer variable using the asterisk (*) symbol followed by the type of variable it points to.

Here’s an example of how to declare and use pointers in Go:

In this example, we declare an integer variable a with a value of 42. We then declare a pointer variable b that points to the memory address of a, using the & operator. We can print out the value of a, the memory address of a, and the value stored at the memory address pointed by b using the * operator to dereference b. Finally, we assign a new value of 21 to the memory location pointed by b, which changes the value of a as well, since b points to the same memory address as a.

Here’s a simple example of a Go program that outputs “Hello, World!”:

Hello world program code using go

Types and Variables

Go is statically typed, which means that you need to specify the type of a variable when you declare it. Go supports several built-in types, including integers, floating-point numbers, and strings. Variables can be declared in the following way:

var x int = 42
var y float64 = 3.14
var z string = "Hello, World!"

Functions

Functions are a core aspect of any programming language, and Go is no exception. Go supports both named and anonymous functions, and they can be defined and called in the following way:

functions in go lang

Concurrency

Go is designed to make it easy to build concurrent applications. Go has a powerful concurrency model that is based on goroutines and channels. Goroutines are lightweight threads that can run in parallel, and channels are a mechanism for communication between goroutines. Here’s an example of how to use channels to communicate between two goroutines:

goroutine and channels

Standard Library

Go has a rich standard library that provides a wide range of functionality, including support for networking, I/O, and concurrency. The standard library is designed to be simple, efficient, and easy to use, making it a powerful tool for developers who want to build high-performance applications.

Data structures in Go

Structs

In Go, you can define a struct using the type and struct keywords, followed by the name of the struct and its field declarations within curly braces. Here’s an example:

type Person struct {
Name string
Age int
Email string
}

This defines a struct named Person with three fields: Name, Age, and Email. To create a new instance of this struct, you can use the Person{} syntax and initialize the fields:

p := Person{Name: "Alice", Age: 30, Email: "alice@example.com"}

To access the fields of a struct, you can use the dot notation:

fmt.Println(p.Name) // prints "Alice"g
fmt.Println(p.Age) // prints 30
fmt.Println(p.Email) // prints "alice@example.com""alice@example.com"

You can also create a pointer to a struct using the & operator, and access the fields using the -> operator:

pPtr := &p

fmt.Println(pPtr->Name) // prints "Alice"pPtr->Name) // prints "Alice"

Arrays

To use arrays in Go, you can follow these basic steps:

  1. Declare an array variable:
var arrayName [size]datatype

2. Initialize the array elements:

arrayName := [size]datatype{value1, value2, value3, …}

3. Access the array elements using their index, which starts at 0:

arrayName[index]

Here’s an example of creating and using an array of integers:

Slices

In Go, you can use slices to extract a portion of an array or another slice. Here’s how to use slices in Go:

  • Declare a slice:
slice := []int{1, 2, 3, 4, 5}
  • Basic slice expression:

slice[start:end] // start and end are integer indices . This will return a new slice that includes the elements from index start to end-1.

  • Slice expression with an omitted start index:

slice[:end] // includes all elements up to, but not including, end

  • Slice expression with an omitted end index:

slice[start:] // includes all elements from start to the end of the slice

  • Slice expression with both start and end indices omitted:

slice[:] // returns a new slice with all the elements of the original slice

  • Modifying a slice:

You can modify a slice by assigning a new value to a slice element or using the built-in append function.

slice[2] = 10 // change the value of the third element to 10

slice = append(slice, 6) // append 6 to the end of the slice

Maps

In Go, maps are a built-in data type for key-value pairs, similar to dictionaries in Python or hashes in Ruby.

Here’s how to use maps in Go:

  1. Create a map: To create a map, use the make function with the map type:
m := make(map[string]int)

In this example, the map m is created with keys of type string and values of type int.

2. Add elements:

You can add elements to a map using the square bracket notation:

m["key1"] = 1
m["key2"] = 2

3. Access elements: You can access elements in a map using the square bracket notation:

value1 := m["key1"]
value2 := m["key2"]

4. Check if a key exists: You can use the _, ok idiom to check if a key exists in a map:

value, ok := m["key3"]
if !ok {
fmt.Println("Key does not exist")
}

5. Iterate over a map: You can use a for loop with the range keyword to iterate over a map:

for key, value := range m {
fmt.Println(key, value)
}

Error handling in go

In Go, errors are represented as values of the “error” type. Functions can return an error value to indicate that something went wrong, and the calling code can handle the error using the “if err != nil” idiom.

Go also provides the “panic” and “recover” mechanisms for handling more serious errors. “Panic” is used to signal that something unexpected happened and the program cannot continue. “Recover” is used to catch and handle panics, and is typically used in a deferred function.

In general, Go encourages programmers to handle errors explicitly and to avoid using exceptions as much as possible.

If the “doSomething” function encounters an error, it returns an error value created using the “errors.New” function. The calling code checks for the error by using the “if err != nil” idiom and handles it as appropriate.

Go also provides the “panic” and “recover” mechanisms for handling more serious errors, but it’s generally better to handle errors explicitly using the “error” type.

In conclusion, Go is a modern, efficient programming language that is well-suited for developing web services, cloud-native applications, and other systems-level software. Whether you are a seasoned developer or just starting out, Go is an excellent choice for your next project, thanks to its straightforward syntax, powerful concurrency model, and rich standard library.

--

--