Osvojte si komplexní znalosti o cyklech `for` v jazyce Golang prostřednictvím praktických ukázek kódu.
Programovací jazyky jako Rust, Golang a TypeScript si v poslední době získaly značnou oblibu mezi vývojáři. Pokud se zajímáte o vývoj backendu a DevOps, rozhodně byste měli zvážit Golang jako vynikající volbu pro studium!
Pro začátečníky, kteří si osvojili základy programování, jsou smyčkové konstrukce jedním z prvních konceptů, které je třeba pochopit.
Golang nabízí pouze konstrukci cyklu `for`. V tomto článku se podíváme na to, jak používat cykly `for` a jak pomocí nich simulovat jiné typy smyček.
Začněme!
Syntaxe cyklu `for` v jazyce Golang
V jazyce Golang můžete vytvořit cyklus `for` pomocí následující syntaxe:
for inicializace; podmínka; aktualizace { // provede se nějaká akce }
Kde:
- `inicializace` slouží k nastavení počáteční hodnoty proměnné cyklu.
- `podmínka` je logický výraz, který určuje, zda se tělo smyčky má provést. Příkazy v těle smyčky se vykonávají, dokud je podmínka splněna. Jakmile se podmínka vyhodnotí jako `false`, cyklus se ukončí.
- `aktualizace` slouží k úpravě hodnoty proměnné cyklu – obvykle se jedná o inkrementaci nebo dekrementaci.
💡 Je dobré si všimnout, že tato syntaxe je podobná cyklu `for` v jazyce C, ale bez závorek.
Následující obrázek znázorňuje tok řízení v cyklech `for` v jazyce Golang:
Je čas na praktické příklady! ⏰ Pro kódování můžete použít lokální instalaci Golangu nebo online prostředí Go Playground.
Příklady použití cyklu `for` v jazyce Golang
Použijme syntaxi, kterou jsme se naučili, k napsání našeho prvního cyklu `for`. Následující jednoduchý cyklus `for` vypíše čísla od 1 do 5, s krokem 1.
package main import "fmt" func main() { fmt.Println("Cyklus for:") num := 5 for i := 1; i <= num; i++ { fmt.Println(i) } }
Proměnnou cyklu `i` inicializujeme na 1, nastavíme podmínku `i <= 5` a po každé iteraci zvýšíme proměnnou cyklu o jedna. Zde je výstup:
//Výstup Cyklus for: 1 2 3 4 5
Nyní napíšeme další cyklus `for`. Tento cyklus začíná od 5 a snižuje se až do 1. Běží dokud je proměnná cyklu větší nebo rovna 1. Po každé iteraci snižujeme proměnnou cyklu o jedna.
package main import "fmt" func main() { fmt.Println("Cyklus for:") num := 5 for i := num; i >= 1; i-- { fmt.Println(i) } }
A zde je očekávaný výstup:
//Výstup Cyklus for: 5 4 3 2 1
Jaký je rozsah proměnné cyklu?
Rozsah proměnné cyklu je omezen na blok cyklu `for` a není přístupná mimo něj.
Abychom to ověřili, pokusíme se přistoupit k hodnotě proměnné cyklu `i` mimo cyklus:
package main import "fmt" func main() { fmt.Println("Cyklus for:") num := 5 for i := 1; i <= num; i++ { fmt.Println(i) } fmt.Println(i) }
Jak se očekávalo, dojde k chybě, která hlásí, že `i` není definováno (jeho rozsah je omezen na cyklus `for`):
// Výstup ./prog.go:11:14: undefined: i
Nekonečný cyklus `for` v jazyce Golang
Je možné mít v Go nekonečné cykly `for`? Ano, je to rozhodně možné!
Pokud se podíváte na tok řízení cyklu `for`:
- Tělo smyčky se bude provádět, dokud se podmínka vyhodnotí jako pravda.
- Když se podmínka vyhodnotí jako nepravda, cyklus se ukončí.
- Pokud se tedy podmínka nikdy nevyhodnotí jako nepravda (nebo je vždy pravda), máme nekonečný cyklus.
Je také možné použít cyklus `for` bez inicializace, podmínky a aktualizace, aniž by to způsobilo chybu syntaxe. Můžete tedy vytvořit nekonečnou smyčku i pomocí konstrukce cyklu `for` jako v tomto příkladu:
package main import "fmt" func main() { for { fmt.Println("běží...") } }
//Výstup běží... běží... běží... běží... běží... //a tak dále donekonečna!
V tomto příkladu jsme nastavili proměnnou `num` na 5. Podmínka cyklu je `num >= 0`. Cyklus tedy běží, dokud je `num` větší nebo rovno nule.
package main import "fmt" func main() { num := 5 for num > 0 { fmt.Println(num) } }
Protože se hodnota `num` nikdy nemění, podmínka se vyhodnocuje vždy jako pravda a cyklus běží nekonečně!
//Výstup 5 5 5 5 5 5 //a tak dále donekonečna!
Vzhledem k tomu, že Golang má pouze konstrukci cyklu `for`, můžeme se pokusit emulovat cykly `while` a `do-while` pomocí cyklů `for`. Podívejme se tedy, jak na to!
Emulace cyklu `while` pomocí cyklu `for`
Cyklus `while` má obecně následující podobu:
// inicializovat proměnnou cyklu while (podmínka){ // provést nějakou akci // aktualizovat proměnnou cyklu }
Jak si pamatujete, v prvním příkladu nekonečného cyklu `for` jsme použili následující cyklus `for` – bez inicializace, podmínky a aktualizace.
for { // nejjednodušší nekonečný cyklus }
Můžeme tedy upravit cyklus `for` tak, aby obsahoval pouze podmínku (v následující formě) pro emulaci cyklu `while`:
//inicializovat proměnnou cyklu for podmínka { // provést nějakou akci // aktualizovat proměnnou cyklu }
Zde je ekvivalent cyklu `while` k prvnímu cyklu `for`, který jsme napsali:
package main import "fmt" func main() { fmt.Println("Emulace cyklu while") num := 5 for num > 0 { fmt.Println(num) num-- } }
//Výstup Emulace cyklu while 5 4 3 2 1
Emulace cyklu `do-while` pomocí cyklu `for`
Pokud máte zkušenosti s kódováním v jazyce jako C, víte, že konstrukce cyklu `do-while` má následující podobu:
// inicializovat proměnnou cyklu do { //nějaká akce // aktualizovat proměnnou cyklu } while(podmínka);
Hlavní rozdíl mezi cykly `while` a `do-while` je v tom, že cyklus `while` kontroluje podmínku při vstupu do smyčky. Naproti tomu cyklus `do-while` kontroluje podmínku při výstupu ze smyčky.
Pokud se tedy v cyklu `while` podmínka vyhodnotí jako nepravda, tělo smyčky se nikdy nespustí. V cyklu `do-while` se však tělo smyčky provede, i když se podmínka vyhodnotí jako nepravda.
S těmito informacemi můžeme emulovat chování cyklu `do-while`:
- Napíšeme nekonečný cyklus `for`
- Použijeme podmíněný příkaz `if` se správnou podmínkou pro ukončení smyčky
Řekněme, že chceme napsat cyklus `do-while`, kde podmínka pro provedení těla smyčky je `num < 0`. Můžeme napsat cyklus `for` a ukončit smyčku, pokud `num >= 0`.
package main import "fmt" func main() { fmt.Println("Emulace cyklu do-while") num := 5 for { fmt.Println("cyklus běží...") if num >= 0 { break } } }
💡 Je důležité poznamenat, že provedení smyčky, pokud `num < 0`, a ukončení smyčky, pokud `num >= 0`, jsou ekvivalentní podmínky.
Ačkoli je podmínka `num > 0` zpočátku nepravdivá (`num` je 5), tělo smyčky se spustí jednou a emuluje cyklus `do-while`.
//Výstup Emulace cyklu do-while cyklus běží...
Cyklus přes pole pomocí cyklu `for`
Při procházení polí v Golangu pomocí cyklu `for` a `range` máte přístup jak k indexům, tak k prvkům. Funguje to podobně jako funkce `enumerate` v Pythonu.
Zde vytvoříme `numArray`, pole celých čísel. A projdeme jím pomocí cyklu `for`:
package main import "fmt" func main() { fmt.Println("Procházení pole") numArray := []int{3, 7, 0, 10, 8, 9} for idx, num := range numArray { fmt.Println("Na indexu", idx, ": ", num) } }
Jak vidíme, můžeme přistupovat k indexu i prvku na každém indexu současně:
//Výstup Procházení pole Na indexu 0 : 3 Na indexu 1 : 7 Na indexu 2 : 0 Na indexu 3 : 10 Na indexu 4 : 8 Na indexu 5 : 9
Použití `defer` v cyklu `for` v jazyce Golang
V jazyce Golang můžete použít klíčové slovo `defer` k odložení volání funkcí.
Ačkoli se používá v aplikacích, jako je uvolňování zdrojů a zpracování chyb, je užitečné porozumět tomu, jak používat `defer` uvnitř cyklu `for`. Podívejme se, co se stane, když použijeme `defer` uvnitř cyklu `for` k odložení volání funkce `Println()`.
package main import "fmt" func main() { fmt.Println("Cyklus for:") num := 5 for i := 1; i <= num; i++ { defer fmt.Println(i) } }
💬 Když je volání funkce odloženo, uloží se do zásobníku a provede se v pořadí LIFO (Last-In-First-Out). K tomuto provedení dojde až po ukončení funkce, která volání `defer` obklopuje.
Takže `fmt.Println(5)` se provede jako první a `fmt.Println(1)` se provede jako poslední:
//Výstup Cyklus for: 5 4 3 2 1
Závěr
Zde je shrnutí toho, co jste se v tomto tutoriálu naučili:
- V jazyce Golang můžete vytvářet cykly `for` se syntaxí: `for inicializace; podmínka; aktualizace { //tělo cyklu }`.
- Tok řízení cyklu `for` je poměrně jednoduchý. Proměnná cyklu se inicializuje jednou, vyhodnocuje se podmínka pro určení, zda se má provést tělo cyklu, a aktualizuje se proměnná cyklu po každé iteraci.
- Rozsah proměnné cyklu je omezen na tělo cyklu a není přístupná mimo něj.
- Přestože Golang nabízí pouze konstrukci cyklu `for`, můžete emulovat chování cyklů `while` a `do-while` pomocí cyklů `for`.
- Mezi další aplikace cyklu `for` patří procházení polí a odkládání volání funkcí uvnitř těla cyklu `for`.
Dále se naučte, jak používat cykly `for` v Pythonu. Přeji příjemné učení! 🎉