Lekce 4 - Podmínky (větvení) v Kotlin
V předešlém cvičení, Řešené úlohy k 3. lekci Kotlin, jsme si procvičili nabyté zkušenosti z předchozích lekcí.
Abychom si něco naprogramovali, potřebujeme nějak reagovat na různé situace. Může to být například hodnota zadaná uživatelem, podle které budeme chtít měnit další běh programu. Říkáme, že se program větví a k větvení používáme podmínky. Těm se budeme věnovat celý dnešní Kotlin tutoriál. Vytvoříme program na výpočet odmocniny a vylepšíme naši kalkulačku.
Podmínky
V Kotlin se podmínky píší dost stejně, jako ve všech CLike jazycích, pro začátečníky samozřejmě vysvětlím. Pokročilejší se asi budou chvilku nudit
Podmínky zapisujeme pomocí klíčového slova if
, za kterým
následuje logický výraz. Pokud je výraz pravdivý, provede se následující
příkaz. Pokud ne, následující příkaz se přeskočí a pokračuje se až
pod ním. Vyzkoušejme si to:
{KOTLIN_CONSOLE}
if (15 > 5)
println("Pravda")
println("Program zde pokračuje dál")
{/KOTLIN_CONSOLE}
Výstup programu:
Pravda Program zde pokračuje dál
Pokud podmínka platí (což zde ano), provede se příkaz vypisující do
konzole text Pravda
. V obou případech program pokračuje
dál. Součástí výrazu samozřejmě může být i proměnná:
{KOTLIN_CONSOLE}
println("Zadej nějaké číslo")
val a = readLine()!!.toInt()
if (a > 5)
println("Zadal jsi číslo větší než 5!")
println("Děkuji za zadání")
{/KOTLIN_CONSOLE}
Operátory
Ukažme si nyní relační operátory, které můžeme ve výrazech používat:
Operátor | C-like Zápis |
---|---|
Rovnost | == |
Je ostře větší | > |
Je ostře menší | < |
Je větší nebo rovno | >= |
Je menší nebo rovno | <= |
Nerovnost | != |
Obecná negace | ! |
Rovnost zapisujeme dvěma ==
proto, aby se to nepletlo s
běžným přiřazením do proměnné, které se dělá jen jedním
=
. Pokud chceme nějaký výraz znegovat, napíšeme ho do závorky
a před něj vykřičník. V podmínkovém bloku samozřejmě můžeme vykonat
libovolně příkazů. Pokud vykonáváme více než jeden, vkládáme je do
bloku ze složených závorek:
import kotlin.math.* // Import vždy patří do hlavičky souboru
fun main(args: Array<String>) {
println("Zadej nějaké číslo, ze kterého spočítám odmocninu:")
val a = readLine()!!.toInt()
if (a > 0) {
println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!")
val o = sqrt(a.toDouble())
println("Odmocnina z čísla $a je $o")
}
println("Děkuji za zadání")
}
Výsledek:
Zadej nějaké číslo, ze kterého spočítám odmocninu: 144 Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit! Odmocnina z čísla 144 je 12.0 Děkuji za zadání
Program načte od uživatele číslo a pokud je větší než 0
,
vypočítá z něj druhou odmocninu. Funkce sqrt()
vrací druhou
odmocninu jako Double
, ale musíme nejdříve vstup konvertovat na
Double
. Abychom mohli takového matematické funkce v Kotlin
používat, je třeba nejprve naimportovat kotlin.math
, viz první
řádek zdrojového kódu výše. Bylo by hezké, kdyby nám program vyhuboval v
případě, že zadáme záporné číslo. S dosavadními znalostmi bychom
napsali něco jako:
import kotlin.math.* // Import vždy patří do hlavičky souboru
fun main(args: Array<String>) {
println("Zadej nějaké číslo, ze kterého spočítám odmocninu:")
val a = readLine()!!.toInt()
if (a > 0) {
println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!")
val o = sqrt(a.toDouble())
println("Odmocnina z čísla $a je $o)")
}
if (a <= 0) {
println("Odmocnina ze záporného čísla neexistuje!")
}
println("Děkuji za zadání")
}
Všimněte si, že musíme pokrýt i případ, kdy se a == 0
,
nejen když je menší. Kód však můžeme výrazně zjednodušit pomocí
klíčového slova else
, které vykoná následující příkaz
nebo blok příkazů v případě, že se podmínka
neprovede:
import kotlin.math.* // Import vždy patří do hlavičky souboru
fun main(args: Array<String>) {
println("Zadej nějaké číslo, ze kterého spočítám odmocninu:")
val a = readLine()!!.toInt()
if (a > 0) {
println("Zadal jsi číslo větší než 0, to znamená, že ho mohu odmocnit!")
val o = sqrt(a.toDouble())
println("Odmocnina z čísla $a je $o")
}
else
println("Odmocnina ze záporného čísla neexistuje!")
println("Děkuji za zadání")
}
Kód je mnohem přehlednější a nemusíme vymýšlet opačnou podmínku,
což by v případě složené podmínky mohlo být někdy i velmi obtížné. V
případě více příkazů by byl za else
opět blok
{ }
.
Klíčové slovo else
se také využívá v případě, kdy
potřebujeme v příkazu manipulovat s proměnnou z podmínky a nemůžeme se na
ni tedy ptát potom znovu. Program si sám pamatuje, že se podmínka nesplnila,
a přejde do větve else
. Ukažme si to na příkladu: Mějme
číslo a
, kde bude hodnota 0
nebo 1
a po
nás se bude chtít, abychom hodnotu prohodili (pokud tam je 0
,
dosadíme tam 1
, pokud 1
, dosadíme 0
).
Naivně bychom mohli kód napsat takto:
{KOTLIN_CONSOLE}
var a = 0 // do a si přiřadíme na začátku 0
if (a == 0) { // pokud je a 0, dáme do něj jedničku
a = 1
}
if (a == 1) { // pokud je a 1, dáme do něj nulu
a = 0
}
println(a)
{/KOTLIN_CONSOLE}
Nefunguje to, že? Pojďme si projet, co bude program dělat. Na začátku
máme v a
nulu, první podmínka se jistě splní a dosadí do
a
jedničku. No ale rázem se splní i ta druhá. Co s tím? Když
podmínky otočíme, budeme mít ten samý problém s jedničkou. Jak z toho
ven? Ano, použijeme else
.
{KOTLIN_CONSOLE}
var a = 0 // do a si přiřadíme na začátku 0
if (a == 0) { // pokud je a 0, dáme do něj jedničku
a = 1
} else { // pokud je a 1, dáme do něj nulu
a = 0
}
println(a)
{/KOTLIN_CONSOLE}
Podmínky je možné skládat a to pomocí dvou základních logických operátorů:
Operátor | C-like Zápis |
---|---|
A zároveň | && |
Nebo | || |
Uveďme si příklad:
{KOTLIN_CONSOLE}
println("Zadejte číslo v rozmezí 10-20:")
val a = readLine()!!.toInt()
if (a >= 10 && a <= 20) {
println("Zadal jsi správně")
} else {
println("Zadal jsi špatně")
}
{/KOTLIN_CONSOLE}
S tím si zatím vystačíme, operátory se pomocí závorek samozřejmě dají kombinovat.
{KOTLIN_CONSOLE}
println("Zadejte číslo v rozmezí 10-20 nebo 30-40:")
val a = readLine()!!.toInt()
if (((a >= 10) && (a <= 20)) || ((a >=30) && (a <= 40))) {
println("Zadal jsi správně")
} else {
println("Zadal jsi špatně")
}
{/KOTLIN_CONSOLE}
when
Konstrukce when
je převzatá z jazyka
C (jako velká část gramatiky Kotlin), kde je známá jako konstrukce
switch
. Umožňuje nám zjednodušit (relativně) zápis více
podmínek pod sebou. Vzpomeňme si na naši kalkulačku v prvních lekcích,
která načetla 2
čísla a vypočítala všechny 4
operace. Nyní si ale budeme chtít zvolit, kterou operaci chceme. Bez
when
bychom napsali kód podobný tomuto:
{KOTLIN_CONSOLE}
println("Vítejte v kalkulačce")
println("Zadejte první číslo:")
val a = readLine()!!.toDouble()
println("Zadejte druhé číslo:")
val b = readLine()!!.toDouble()
println("Zvolte si operaci:")
println("1 - sčítání")
println("2 - odčítání")
println("3 - násobení")
println("4 - dělení")
val volba = readLine()!!.toInt()
var vysledek: Double = 0.0
if (volba == 1) {
vysledek = a + b
} else if (volba == 2) {
vysledek = a - b
} else if (volba == 3) {
vysledek = a * b
} else if (volba == 4) {
vysledek = a / b
}
if ((volba > 0) && (volba < 5)) {
println("Výsledek: $vysledek")
} else {
println("Neplatná volba")
}
println("Děkuji za použití kalkulačky.")
{/KOTLIN_CONSOLE}
Výstup:
Vítejte v kalkulačce Zadejte první číslo: 3,14 Zadejte druhé číslo: 2,72 Zvolte si operaci: 1 - sčítání 2 - odčítání 3 - násobení 4 - dělení 2 Výsledek: 0,42 Děkuji za použití kalkulačky.
Všimněte si, že jsme proměnnou vysledek
deklarovali na
začátku, jen tak do ni můžeme potom přiřazovat. Kdybychom ji deklarovali u
každého přiřazení, Kotlin by kód nezkompiloval a vyhodil chybu redeklarace
proměnné. Proměnná může být deklarována (založena v paměti) vždy jen
jednou. Bohužel Kotlin není schopen poznat, zda je do proměnné
vysledek
opravdu přiřazena nějaká hodnota. Ozve se při výpisu
na konzoli, kde se mu nelíbí, že může vypisovat proměnnou, která nemá
přiřazenu hodnotu. Z tohoto důvodu na začátku dosadíme do
vysledek
nulu.
Další vychytávka je kontrola správnosti volby. Program by v tomto
případě fungoval stejně i bez těch else
, ale nač se dále
ptát, když již máme výsledek.
Nyní si zkusíme napsat ten samý kód pomocí when
:
{KOTLIN_CONSOLE}
println("Vítejte v kalkulačce")
println("Zadejte první číslo:")
val a = readLine()!!.toDouble()
println("Zadejte druhé číslo:")
val b = readLine()!!.toDouble()
println("Zvolte si operaci:")
println("1 - sčítání")
println("2 - odčítání")
println("3 - násobení")
println("4 - dělení")
val volba = readLine()!!.toInt()
var vysledek: Double = 0.0
when (volba) {
1 -> vysledek = a + b
2 -> vysledek = a - b
3 -> vysledek = a * b
4 -> vysledek = a / b
}
if ((volba > 0) && (volba < 5)) {
println("Výsledek: $vysledek")
} else {
println("Neplatná volba")
}
println("Děkuji za použití kalkulačky.")
{/KOTLIN_CONSOLE}
Vidíme, že kód je trochu přehlednější. Pokud bychom potřebovali v
nějaké větvi when
spustit více příkazů, budeme je psát do
bloku { }
. V původním switch
z jazyka C se
jednotlivé větve musely ukončovat příkazem break
, v Kotlin
toto neplatí a v případě when
vždy provede pouze jednu z nich.
Konstrukce when
může místo x ->
obsahovat
ještě možnost else ->
, která se vykoná v případě, že
nebude platit žádná větev. Je jen na vás, jestli budete when
používat, obecně se vyplatí jen při větším množství příkazů a vždy
jde nahradit sekvencí if
a else
. Samozřejmě lze
použít when
i pro hodnoty String
ové proměnné.
V následujícím cvičení, Řešené úlohy k 4. lekci Kotlin, si procvičíme nabyté zkušenosti z předchozích lekcí.
Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 45x (12.24 kB)
Aplikace je včetně zdrojových kódů v jazyce Kotlin