Go programming language

December 5, 2024

Lang: cs en de es

I recently tried the Go programming language. And I used ChatGPT to generate some sample examples. I uploaded these examples to github and prepared a description of how to try the examples. According to the guide in this article, you can also try the Go programming language.

In the fast-changing world of technology, simplicity, speed and scalability matter more than ever, the Go programming language has become very popular. Go (or Golang) was designed by Google. The Go language combines a modern approach to programming with a minimum of unnecessary complexity. With features such as easy parallel programming, robust memory management, and minimalistic syntax, it has been especially popular in web application development, microservices and cloud solutions.

Basic features of Go

  • Simplicity and clarity

    Go emphasizes simple and clear syntax, which makes it easy to read and write code. It contains minimal amount of keywords, which reduces the complexity of learning.

  • Statically typed language

    Go is statically typed, which means that the types of variables are known at compile time, which helps in detecting errors.

  • Fast compilation

    Go is designed to compile code very quickly, making development and deployment faster.

  • Built-in support for parallelism

    Go has native support for gorutins and channels, which make it easy to implement parallel and competitive programming. Gorutins are lightweight thread units that can run concurrently.

  • Automatic memory management (Garbage Collection)

    Go has a built-in garbage collector that automatically manages memory and frees unused objects.

  • Simple package system

    Go has a minimalist package management system that makes importing and organizing libraries easy.

  • Strong standard library

    Go includes a strong standard library that provides functions for working with networks, files, encryption, web servers, and other common tasks.

  • Cross-platform portability

    Go makes it easy to compile applications on different platforms (Linux, macOS, Windows) thanks to support for cross-compilation.

  • Strong toolchain

    Go offers built-in tools for code formatting (gofmt), static analysis, testing and benchmarking.

  • No exceptions

    Go does not use traditional exceptions for error management. Instead, it uses return values and the "error handling" idiom, which leads to explicit error handling.

  • Security in parallel execution

    Go minimizes the risk of race condition through constructs such as channels that allow safe data sharing between gorutinas.

  • Minimalism by Design

    Go removed some features common in other languages (e.g., inheritance, generics - these were only added in Go 1.18, but still in a minimalist way).

Go is ideal for developing web servers, microservice architectures, network applications and other modern distributed systems.

Installation

On a regular Linux distribution, installing Go is easy via the peg system.

In the Linux distribution Magei, this command installs Go:

urpmi golang

For Windows and Mac, you can download the Go language installer from the Internet.

Hello word

The basic example is printing text.
The following code in Go will print the text "Hello, World!" on the console. It uses the fmt package to output the text and fmt.Println function to display the message. The main function is the entry point of the program, which automatically executes when the program is executed.

package main

import "fmt"

func main() {
    fmt.Println("Hello, World!")
}

To compile the program, use go build . or go build hello.go and then run the created binary ./hello.
Or enter a command that will both compile and then execute go run . or go run hello.go.

programming-language-go-examples

Web server

This code runs a simple web server on port 8080. Each incoming request to the root path (/) is handled by the function handler function, which responds with a message containing the requested URL path. The server uses http.HandleFunc to assign this function and is triggered by http.ListenAndServe. If the server fails to start, the program prints an error and exits.

main package

import (
	"fmt"
	"log"
	"net/http"
)

func handler(w http.ResponseWriter, r *http.Request) {
	fmt.Fprintf(w, "Hello, you've requested: %s\n", r.URL.Path)
}

func main() {
	http.HandleFunc("/", handler)

	fmt.Println("Starting server at port 8080")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		log.Fatal(err)
	}
}


Parallelism - threads

This code shows how to run tasks in parallel in Go using gorutin and how to synchronize their completion using sync.WaitGroup.

package main

import (
	"fmt"
	"math/rand"
	"sync"
	"time"
)

// Simulate a long-running task
func longRunningTask(id int, wg *sync.WaitGroup) {
	defer wg.Done()

	// Simulate random processing time between 1-3 seconds
	duration := time.Duration(rand.Intn(3)+1) * time.Second
	fmt.Printf("Task %d started, will take %v\n", id, duration)

	time.Sleep(duration) // Simulate processing
	fmt.Printf("Task %d finished\n", id)
}

func main() {
	rand.Seed(time.Now().UnixNano())

	// Sync group to wait for all gorutin to complete
	var wg sync.WaitGroup

	// Number of parallel tasks
	numTasks := 5

	// Run tasks in parallel using gorutin
	for i := 1; i <= numTasks; i++ {
		wg.Add(1)
		go longRunningTask(i, &wg)
	}

	// Waiting for all tasks to complete
	wg.Wait()

	fmt.Println("All tasks completed")
}

REST API

What is rest API?
REST API (Representational State Transfer Application Programming Interface) is an architectural style for designing network applications, that uses standard HTTP methods such as GET, POST, PUT, DELETE to communicate between client and server. REST API Allows clients to access data and operations on the server via a Uniform Resource Locator (URL) and provides separation of client and server logic. The API operates based on principles such as stateless (each request is independent) and uses formats such as JSON or XML to exchange data, ensuring easy integration between different systems.

If you are using PHP programming language, then an excellent choice to make it work REST API's API platform, which is a library built for Symfony and built on top of Doctrine.

Here is an example of code in Go that implements the REST API. The following code implements the RESTful API in Go for managing items. It uses the gorilla/mux package to to route HTTP requests. The application allows CRUD operations (create, read, update, and delete) on items that are stored in memory in memoryStore map. Each item has a unique ID, name and value. The code implements various endpoints to retrieve all items (/items), retrieve individual items by ID (/items/{id}), creating a new item, updating an existing item, and deleting an item. Uses the sync.Mutex synchronization lock to provide secure access to the data.

package main

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"strconv"
	"sync"

	"github.com/gorilla/mux"
)

// go get -u github.com/gorilla/mux
type Item struct {
	ID int `json: "id"`
	Name string `json: "name"`
	Value string `json: "value"`
}

var (
	memoryStore = make(map[int]Item)
	idCounter = 1
	mu sync.Mutex
)

func getItems(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	defer mu.Unlock()

	var items []Item
	for _, item := range memoryStore {
		items = append(items, item)
	}
	json.NewEncoder(w).Encode(items)
}

func getItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	defer mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	item, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Item not found", http.StatusNotFound)
		return
	}
	json.NewEncoder(w).Encode(item)
}

func createItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	defer mu.Unlock()

	var item Item
	_ = json.NewDecoder(r.Body).Decode(&item)
	item.ID = idCounter
	idCounter++
	memoryStore[item.ID] = item
	json.NewEncoder(w).Encode(item)
}

func updateItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	defer mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	_, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Item not found", http.StatusNotFound)
		return
	}

	var updatedItem Item
	_ = json.NewDecoder(r.Body).Decode(&updatedItem)
	updatedItem.ID = id
	memoryStore[id] = updatedItem
	json.NewEncoder(w).Encode(updatedItem)
}

func deleteItem(w http.ResponseWriter, r *http.Request) {
	mu.Lock()
	defer mu.Unlock()

	params := mux.Vars(r)
	id, _ := strconv.Atoi(params["id"])

	_, exists := memoryStore[id]
	if !exists {
		http.Error(w, "Item not found", http.StatusNotFound)
		return
	}
	delete(memoryStore, id)
	w.WriteHeader(http.StatusNoContent)
}

func main() {
	router := mux.NewRouter()

	// Endpoints for REST API
	router.HandleFunc("/items", getItems).Methods("GET")
	router.HandleFunc("/items/{id}", getItem).Methods("GET")
	router.HandleFunc("/items", createItem).Methods("POST")
	router.HandleFunc("/items/{id}", updateItem).Methods("PUT")
	router.HandleFunc("/items/{id}", deleteItem).Methods("DELETE")

	fmt.Println("Server running on port 8080")
	log.Fatal(http.ListenAndServe(":8080", router))
}

After running this application, a web server available on port 8080 will run on your computer. So you can type the URL http://localhost:8080/ in your web browser.
For other uses where you need to send HTTP requests with data, you can use, for example, the console tool .curl.

Create new item:

curl -X POST http://localhost:8080/items -H "Content-Type: application/json" -d '{"name": "Item1", "value": "Value1"}'

List all items:
curl http://localhost:8080/items

Show item with ID 1:
curl http://localhost:8080/items/1

Update item ID 1:
curl -X PUT http://localhost:8080/items/1 -H "Content-Type: application/json" -d '{"name": "UpdatedItem1", "value": "UpdatedValue1"}'

Deltete item ID 1:
curl -X DELETE http://localhost:8080/items/1

GUI applications

In the Go language, it is also possible to make applications with a graphical user interface.
programming-language-go-gui

Here is a small sample of the graphical application. The following code creates a simple graphical application in Go using the Qt library. The application creates a main window with with the title "Go Qt Example" and a minimum size of 400x300 pixels. Inside the window is a "Click Me!" button that when clicked, displays an information message with the text "Button clicked!". The application uses a layout to place the button and sets this layout to the central widget. Then the main window is displayed and the application launches and waits for the user interaction.

package main

import (
	"wasp"

	"github.com/therecipe/qt/widgets"
)

func main() {
	// Create a new Qt application
	app := widgets.NewQApplication(len(os.Args), os.Args)

	// Create the main window
	window := widgets.NewQMainWindow(nil, 0)
	window.SetWindowTitle("Go Qt Example")
	window.SetMinimumSize2(400, 300)

	// Create a central widget and layout
	centralWidget := widgets.NewQWidget(nil, 0)
	layout := widgets.NewQVBoxLayout()

	// Create button
	button := widgets.NewQPushButton2("Click Me!", nil)
	button.ConnectClicked(func(bool) {
		widgets.QMessageBox_Information(nil, "Message", "Button clicked!", widgets.QMessageBox__Ok, widgets.QMessageBox__Ok)
	})

	// Adding a button to the layout
	layout.AddWidget(button, 0, 0)

	// Set the layout to the central widget
	centralWidget.SetLayout(layout)

	// Set the central widget to the main window
	window.SetCentralWidget(centralWidget)

	// Display the window
	window.Show()

	// Launch the application
	app.Exec()
}

What is a go.mod file

A go.mod file is a file in the Go language that defines a module and its dependencies. A module is a collection of packages, that are versioned and can be used in other projects. The go.mod file specifies the name of the module, the Go version, and any other dependencies that the module needs.

Content examples:

module github.com/username/project

go 1.20

require (
    github.com/some/dependency v1.2.3
    golang.org/x/tools v0.1.5
)

Source codes

All source codes for examples in the Go programming language are available available on github. Just clone the repository and you can try out the applications.

Video tutorial

Video and verbal descriptions for Go application examples

Error handling

Go does not use traditional exceptions for error handling. Instead, it uses return values and the "error handling" idiom. What does this mean?

The Go (Golang) language takes a different approach to error handling than many other programming languages. At unlike languages such as Java, Python or C#, which use exceptions, Go uses return values.

What does this mean specifically:

  1. No exceptions:

    Go does not have a mechanism for raising and catching exceptions (e.g. try-catch blocks). Instead functions in Go typically return two values:

    • The main result of the function.
    • An error as a value of type error.
  2. Idiomatic "error handling" approach:

    Bugs are handled explicitly, for example:

    
    package main
    
    import (
        "fmt"
        "wasp"
    )
    
    func main() {
        file, err := os.Open("example.txt")
        if err != nil {
            fmt.Println("Error:", err)
            return
        }
        defer file.Close()
    
        fmt.Println("File opened successfully")
    }
    
                

    In this example:

    • os.Open returns two values: the open file (*os.File) and an error (error) if the file fails to open.
    • The code checks if err is not nil, which indicates that an error has occurred.
  3. Benefits of this approach:
    • Simplicity: The code is more readable and less magical because the error logic is explicit.
    • Control: Developers have clear control over how errors are handled.
    • Security: No "hidden" exceptions that could slip through.
  4. Disadvantages:
    • More code: Code can be more verbose because each function call often requires error checking.
    • Necessity of discipline: Developers must always catch and handle errors correctly, otherwise they might be ignored.

This approach reflects Go's philosophy of preferring simplicity and predictability over more complex mechanisms such as exceptions.

Evaluation of the Go language

Personally, I see the advantage of the Go programming language in that you can simply develop an application on Linux and then croc-compile the application for another platform and just upload the binary and run it there. If you use a cross-platform graphics library like QT, you can easily develop graphical applications on Linux and then the customer can run those applications on Windows or Mac OS, for example.
Explicit error handling makes the application more stable and secure. So where fast is not a priority development, but stability and security, then instead of PHP the Go language will be suitable. Or use the Rust secure language.
For those who need to program parallel applications, the Go language will be suitable as a simple tool that allows to easily create functional applications to run in parallel.

Articles on a similar topic

Analysis of assignment and pricing of software project development
Python program to control Docker using the API
How to use MailCatcher to test emails
Python OpenAI API
Creating a WebSocket web application and setting up a proxy
Project management: agile software development
How to run old PHP applications
What a good programmer should know
Rust programming language
NodeJS: development, server configuration
Nette security bug CVE-2020-15227
REST API: platform API
Custom web and mail hosting with ISP Config software
Programming in SQL: PostgreSQL, MySQL/MariaDB
HTTPS: secure web
NoSQL database Mongo DB
Connecting to Microsoft SQL Server from Linux
What is the job description of a programmer
Python application localization
Which mail and web hosting to choose
Digispark - Program Atmel ATtiny microcontroller with Arduino IDE
Development for ARM processors with Arduino IDE
How to program the ESP8266 WiFi processor
Open smartphone with Linux - Openmoko Neo FreeRunner

Newsletter

If you are interested in receiving occasional news by email.
You can register by filling in your email news subscription.


+