Programovací jazyk Go
5. prosince 2024Nedá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
.
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.
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á:
-
Žá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
.
-
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ě.
-
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.
-
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.
+