Programovací jazyk Go

5. prosince 2024

Lang: cs en de es

Nedávno jsem vyzkoušel programovací jazyk Go. A pomocí ChatGPT jsem si nechal vygenerovat několik ukázkových příkladů. Tyto příklady jsem nahrál na github a připravil popis jak si dané příklady vyzkoušet. Podle návodu v tomto článku si můžete programovací jazyk Go vyzkoušet i vy.

V rychle se měnícím světě technologií, kde na jednoduchosti, rychlosti a škálovatelnosti záleží více než kdy dříve, si programovací jazyk Go získal velkou popularitu. Go (nebo také Golang) navrhla firma Google. Jazyk Go spojuje moderní přístup k programování s minimem zbytečné složitosti. Díky svým vlastnostem, jako je snadné paralelní programování, robustní správa paměti a minimalistická syntaxe, se uchytil hlavně ve vývoji webových aplikací, mikroservis a cloudových řešení.

Základní vlastnosti jazyka Go

  • Jednoduchost a přehlednost

    Go klade důraz na jednoduchou a srozumitelnou syntaxi, což usnadňuje čtení a psaní kódu. Obsahuje minimální množství klíčových slov, což snižuje složitost učení.

  • Staticky typovaný jazyk

    Go je staticky typovaný, což znamená, že typy proměnných jsou známé během překladu (kompilace), což pomáhá při odhalování chyb.

  • Rychlá kompilace

    Go je navrženo tak, aby se kód kompiloval velmi rychle, díky čemuž je vývoj a nasazení rychlejší.

  • Vestavěná podpora pro paralelismus

    Go má nativní podporu pro gorutiny a kanály, které umožňují snadno implementovat paralelní a konkurenční programování. Gorutiny jsou lehké vláknové jednotky, které mohou běžet současně.

  • Automatická správa paměti (Garbage Collection)

    Go má vestavěný garbage collector, který automaticky spravuje paměť a uvolňuje nepoužívané objekty.

  • Jednoduchý balíčkový systém

    Go má minimalistický systém pro správu balíčků, který usnadňuje import a organizaci knihoven.

  • Silná standardní knihovna

    Go obsahuje rozsáhlou standardní knihovnu, která poskytuje funkce pro práci se sítěmi, soubory, šifrováním, webovými servery a dalšími běžnými úkoly.

  • Cross-platformní přenositelnost

    Go umožňuje snadno kompilovat aplikace na různé platformy (Linux, macOS, Windows) díky podpoře pro cross-kompilaci.

  • Silný nástrojový řetězec

    Go nabízí vestavěné nástroje pro formátování kódu (gofmt), statickou analýzu, testování a benchmarking.

  • Bez výjimek (exceptions)

    Go nepoužívá tradiční výjimky pro správu chyb. Místo toho využívá návratové hodnoty a idiom „error handling“, což vede k explicitnímu zacházení s chybami.

  • Bezpečnost při paralelním běhu

    Go minimalizuje riziko race condition díky konstrukcím, jako jsou kanály, které umožňují bezpečné sdílení dat mezi gorutinami.

  • Minimalismus v návrhu

    Go odstranilo některé vlastnosti běžné v jiných jazycích (např. dědičnost, generika – ty byly přidány až v Go 1.18, ale stále minimalistickým způsobem).

Go je ideální pro vývoj webových serverů, mikroservisních architektur, síťových aplikací a dalších moderních distribuovaných systémů.

Instalace

V běžné linuxové distribuci nainstalujete Go jednoduše a to přes kolíčkovací systém.

V linuxové distribuci Magei nainstaluje Go timto příkazem:

urpmi golang

Pro Windows a Mac můžete z internetu stáhnout instalátor jazyka Go.

Hello word

Základní příklad je vytištění textu.
Následující kód v Go vytiskne na konzoli text "Hello, World!". Používá balíček fmt pro výpis textu a funkci fmt.Println k zobrazení zprávy. Funkce main je vstupní bod programu, který se automaticky spustí při vykonání programu.

package main

import "fmt"

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

Program zkompilujete příkazem go build . nebo go build hello.go a následně spusťte vytvořenou binárku ./hello.
Nebo zadejte příkaz, který provede zároveň kompilaci a následné spuštění go run . nebo go run hello.go.

programing-language-go-examples

Web server

Tento kód spouští jednoduchý webový server na portu 8080. Každý příchozí požadavek na kořenovou cestu (/) je zpracován funkcí handler, která odpoví zprávou obsahující požadovanou URL cestu. Server používá http.HandleFunc k přiřazení této funkce a je spuštěn pomocí http.ListenAndServe. Pokud se server nepodaří spustit, program vypíše chybu a ukončí se.

package main

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)
	}
}


Paralelismus - vlákna

Tento kód ukazuje, jak paralelně spouštět úkoly v Go pomocí gorutin a jak synchronizovat jejich dokončení pomocí sync.WaitGroup.

package main

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

// Simulace dlouhotrvajícího úkolu
func longRunningTask(id int, wg *sync.WaitGroup) {
	defer wg.Done()

	// Simulace náhodné doby zpracování mezi 1-3 sekundami
	duration := time.Duration(rand.Intn(3)+1) * time.Second
	fmt.Printf("Task %d started, will take %v\n", id, duration)

	time.Sleep(duration) // Simulace zpracování
	fmt.Printf("Task %d finished\n", id)
}

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

	// Synchronizační skupina pro čekání na dokončení všech gorutin
	var wg sync.WaitGroup

	// Počet paralelních úkolů
	numTasks := 5

	// Spuštění úkolů paralelně pomocí gorutin
	for i := 1; i <= numTasks; i++ {
		wg.Add(1)
		go longRunningTask(i, &wg)
	}

	// Čekání na dokončení všech úkolů
	wg.Wait()

	fmt.Println("All tasks completed")
}

REST API

Co je rest API?
REST API (Representational State Transfer Application Programming Interface) je architektonický styl pro návrh síťových aplikací, který využívá standardní HTTP metody jako GET, POST, PUT, DELETE pro komunikaci mezi klientem a serverem. REST API umožňuje klientům přístup k datům a operacím na serveru prostřednictvím URL (Uniform Resource Locator) a zajišťuje oddělení klientské a serverové logiky. API funguje na základě principů jako stateless (každý požadavek je nezávislý) a používá formáty jako JSON nebo XML pro výměnu dat, což zajišťuje snadnou integraci mezi různými systémy.

Pokud používáte programovací jazyk PHP, pak výbornou volbou na zprovoznění REST API je API platform, což je knihovna postavená pro Symfony a staví na Doctrine.

Zde je příklad kódu v jazyce Go, který implementuje REST API. Následující kód implementuje RESTful API v Go pro správu položek. Používá balíček gorilla/mux pro směrování HTTP požadavků. Aplikace umožňuje CRUD operace (vytvoření, čtení, aktualizaci a smazání) na položkách, které jsou uloženy v paměti v mapě memoryStore. Každá položka má unikátní ID, název a hodnotu. Kód implementuje různé endpointy pro získání všech položek (/items), získání jednotlivé položky podle ID (/items/{id}), vytvoření nové položky, aktualizaci existující položky a smazání položky. Používá synchronizační zámek sync.Mutex k zajištění bezpečného přístupu k datům.

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()

	// Endpointy pro 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))
}

Po spuštění této aplikace poběží na vašem počítači web server dostupný na portu 8080. Můžete tedy ve webovém prohlížeči zadat URL http://localhost:8080/.
Pro další použití, kdy je potřeba posílat HTTP dotazy s daty můžete použít například konzolový nástroj .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 aplikace

V jazyce Go je možnost i dělat aplikace s grafickým uživatelským rozhraním.
programing-language-go-gui

Zde je malá ukázka grafické aplikace. Následující kód vytváří jednoduchou grafickou aplikaci v Go pomocí knihovny Qt. Aplikace vytvoří hlavní okno s titulkem "Go Qt Example" a minimální velikostí 400x300 pixelů. Uvnitř okna je umístěno tlačítko "Click Me!", které po kliknutí zobrazuje informační zprávu s textem "Button clicked!". Aplikace používá layout pro umístění tlačítka a nastavuje tento layout do centrálního widgetu. Poté se hlavní okno zobrazí a aplikace se spustí a čeká na interakci uživatele.

package main

import (
	"os"

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

func main() {
	// Vytvoření nové Qt aplikace
	app := widgets.NewQApplication(len(os.Args), os.Args)

	// Vytvoření hlavního okna
	window := widgets.NewQMainWindow(nil, 0)
	window.SetWindowTitle("Go Qt Example")
	window.SetMinimumSize2(400, 300)

	// Vytvoření centrálního widgetu a layoutu
	centralWidget := widgets.NewQWidget(nil, 0)
	layout := widgets.NewQVBoxLayout()

	// Vytvoření tlačítka
	button := widgets.NewQPushButton2("Click Me!", nil)
	button.ConnectClicked(func(bool) {
		widgets.QMessageBox_Information(nil, "Message", "Button clicked!", widgets.QMessageBox__Ok, widgets.QMessageBox__Ok)
	})

	// Přidání tlačítka do layoutu
	layout.AddWidget(button, 0, 0)

	// Nastavení layoutu do centrálního widgetu
	centralWidget.SetLayout(layout)

	// Nastavení centrálního widgetu do hlavního okna
	window.SetCentralWidget(centralWidget)

	// Zobrazení okna
	window.Show()

	// Spuštění aplikace
	app.Exec()
}

Co je soubor go.mod

Soubor go.mod je v jazyce Go soubor, který definuje modul a jeho závislosti. Modul je kolekce balíčků (packages), které jsou verziované a mohou být použity v jiných projektech. Soubor go.mod specifikuje název modulu, verze Go, a další závislosti, které modul potřebuje.

Příklady obsahu:

module github.com/username/project

go 1.20

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

Zdrojové kódy

Veškeré zdrojové kódy příkladů v programovacím jazyce Go jsou k dispozici na githubu. Stačí klonovat repositář a můžete si aplikace vyzkoušet.

Video návod

Video a slovní popis k příkladům aplikací v jazyce Go

Správa chyb - error handling

Go nepoužívá tradiční výjimky pro správu chyb. Místo toho využívá návratové hodnoty a idiom „error handling“. Co to znamená?

Jazyk Go (Golang) přistupuje ke správě chyb odlišně než mnoho jiných programovacích jazyků. Na rozdíl od jazyků jako Java, Python nebo C#, které používají výjimky (exceptions), Go používá návratové hodnoty.

Co to konkrétně znamená:

  1. Žádné výjimky (exceptions):

    Go nemá mechanismus pro vyvolání a zachytávání výjimek (např. try-catch bloky). Místo toho funkce v Go obvykle vracejí dvě hodnoty:

    • Hlavní výsledek funkce.
    • Chybu jako hodnotu typu error.
  2. Idiomatický přístup „error handling“:

    Chyby se zpracovávají explicitně, například:

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

    V tomto příkladu:

    • os.Open vrací dvě hodnoty: otevřený soubor (*os.File) a chybu (error), pokud se nepodaří soubor otevřít.
    • Kód kontroluje, zda err není nil, což signalizuje, že došlo k chybě.
  3. Výhody tohoto přístupu:
    • Jednoduchost: Kód je více čitelný a méně magický, protože chybová logika je explicitní.
    • Kontrola: Vývojáři mají jasnou kontrolu nad tím, jak se s chybami zachází.
    • Bezpečnost: Žádné „skryté“ výjimky, které by mohly proklouznout.
  4. Nevýhody:
    • Více kódu: Kód může být rozvláčnější, protože každé volání funkce často vyžaduje kontrolu chyby.
    • Nutnost disciplíny: Vývojáři musí vždy správně zachytit a zpracovat chyby, jinak by mohly být ignorovány.

Tento přístup odráží filozofii Go, která preferuje jednoduchost a předvídatelnost před složitějšími mechanismy, jako jsou výjimky.

Zhodnocení jazyka Go

Osobně vidím výhodu programovacího jazyka Go v tom, že můžete jednoduše vyvíjet aplikaci na Linuxu a pak croc-kompilací zkompilovat aplikaci pro jinou platformu a tam jenom nahrát binárku a tu spustit. Pokud použijete multiplatformní grafickou knihovnu jako je QT, tak takto můžete jednoduše vyvíjet grafické aplikace na Linuxu a takové aplikace pak může zákazník provozovat například na Windows Nebo Mac OS.
Explicitní zpracování chyb umožňuje větší stabilitu a bezpečnost aplikace. Takže tam kde není prioritou rychlý vývoj, ale stabilita a bezpečnost, tak se bude místo PHP hodit jazyk Go. Nebo rovnou použijte bezpečný jazyk Rust.
Kdo potřebuje programovat paralelní aplikace, jazyk Go bude pro něj vhodný jako jednoduchý nástroj, který umožňuje jednoduše vytvářet funkční aplikace, které mají pracovat paralelně.

Články na podobné téma

Analýza zadání a nacenění vývoje softwarového projektu
Python program na ovládání Dockeru pomocí API
Jak použít aplikaci MailCatcher pro testování emailů
Návod: Python OpenAI API
Vytvoření WebSocket webové aplikace a nastavení proxy
Řízení projektů: Agilní vývoj softwaru
Jak provozovat staré PHP aplikace
Co by měl umět dobrý programátor
Programovací jazyk Rust
NodeJS: vývoj, konfigurace serveru
Nette security bug CVE-2020-15227
Jak porovnat dvě stejné databáze?
REST API: API platform
Vlastní web a mail hosting se softwarem ISP Config
Programovní v SQL: PostgreSQL, MySQL/MariaDB
HTTPS: zabezpečený web
NoSQL databáze Mongo DB
Připojení k Microsoft SQL Serveru z Linuxu
Co je pracovní náplň programátora
Lokalizace aplikací v jazyce Python
Jaký mail a web hosting vybrat
How to make wireless low power Arduino
Digispark - Programujte mikrokontrolér Atmel ATtiny pomocí Arduino IDE
Program Roulette
Vývoj pro procesory ARM s Arduino IDE
Wireless low power Arduino
Pyradio - Python program for receive Internet radio with text user inteface
UPS monitor pro Android
Bezdrátový bateriově napájený WiFi teploměr
Jak programovat WiFi procesor ESP8266
Comparison IQRF vs Wireless Arduino
Jakou platformu zvolit pro eshop? Například Prestashop
Development kits and gateways for wireless platform IQRF

OpenStreetMap a GPS trasy v mapě na webu
Quickplay
Java program pro přehledné monitorování záložních zdrojů
Čipové kontaktní a bezkontaktní karty Java Card OpenPlatform
Otevřený chytrý telefon s Linuxem - Openmoko Neo FreeRunner
Vývoj pro bezdrátové moduly s procesorem PIC pod GNU/Linux - IQRF
Grafický program pro embeded/mobilní zařízení na vyhledávání dopravního spoje.
O programování a ruzné programy v jazyce Java, Python a dalších
Java program a applet Kalkulačka
Java program na výpočet kvadratické rovnice

Odběr novinek

Pokud máte zájem dostávat příležitostně na email novinky.
Můžete se vyplněním emailu registrovat k odběru novinek.


+