Go programming language
December 5, 2024I 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
.
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.
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:
-
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
.
-
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 notnil
, which indicates that an error has occurred.
-
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.
-
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.
+