ITnetwork summer 2020
Pouze tento týden sleva až 80 % na e-learning týkající se Pythonu
80 % bodů zdarma na online výuku díky naší Letní akci!

Lekce 2 - Proměnné, typový systém a parsování ve Swift

Z minulé lekce Swift kurzu, Úvod do jazyka Swift, platformy a Xcode, již umíme pracovat s Xcode a vytvořit Playground pro spouštění kódu.

Dnes se v Swift tutoriálu podíváme na tzv. typový systém, ukážeme si základní datové typy a práci s proměnnými. Také dojde řeč na rozdíl mezi klíčovými slovy var a let.

Proměnné

Než začneme řešit datové typy, pojďme se shodnout na tom, co je to proměnná (programátoři mi teď jistě odpustí zbytečné vysvětlování). Určitě znáte z matematiky proměnnou (např. x), do které jsme si mohli uložit nějakou hodnotu, nejčastěji číslo. Proměnná je v informatice naprosto to samé, je to místo v paměti počítače, kam si můžeme uložit nějaká data (jméno uživatele, aktuální čas nebo databázi článků). Toto místo má podle typu proměnné také vyhrazenou určitou velikost, kterou proměnná nesmí přesáhnout (např. číslo nesmí být větší než 2 147 483 647).

Proměnná má vždy nějaký datový typ, může to být číslo, znak, text a podobně, záleží na tom, k čemu ji chceme používat. Většinou musíme před prací s proměnnou tuto proměnnou nejdříve tzv. deklarovat, čili říci jazyku jak se bude jmenovat a jakého datového typu bude (jaký v ní bude obsah). Jazyk ji v paměti založí a teprve potom s ní můžeme pracovat. Podle datového typu proměnné si ji jazyk dokáže z paměti načíst, modifikovat, případně ji v paměti založit. O každém datovém typu jazyk ví, kolik v paměti zabírá místa a jak s tímto kusem paměti pracovat.

Typový systém

Existují dva základní typové systémy: statický a dynamický:

  • Dynamický typový systém nás plně odstiňuje od toho, že proměnná má vůbec nějaký datový typ. Ona ho samozřejmě vnitřně má, ale jazyk to nedává najevo. Dynamické typování jde mnohdy tak daleko, že proměnné nemusíme ani deklarovat, jakmile do nějaké proměnné něco uložíme a jazyk zjistí, že nebyla nikdy deklarována, sám ji založí. Do té samé proměnné můžeme ukládat text, potom objekt uživatele a potom desetinné číslo. Jazyk se s tím sám popere a vnitřně automaticky mění datový typ. V těchto jazycích jde vývoj rychleji díky menšímu množství kódu, zástupci jsou např. PHP nebo Ruby.
  • Statický typový systém naopak striktně vyžaduje definovat typ proměnné a tento typ je dále neměnný. Jakmile proměnnou jednou deklarujeme, není možné její datový typ změnit. Jakmile se do textového řetězce pokusíme uložit objekt uživatel, dostaneme vynadáno.

Swift je staticky typovaný jazyk, všechny proměnné mají pevně daný datový typ, ten ale jako programátor nemusíte tolik řešit. Kompilátor sám "na pozadí" doplní vhodný datový typ, můžete ho ale určit i explicitně. Obrovskou výhodou je, že nám kompiler před spuštěním zkontroluje, zda všechny datové typy sedí. Dynamické typování sice vypadá jako výhodné, ale zdrojový kód není možné automaticky kontrolovat a když někde očekáváme objekt uživatel a přijde nám tam místo toho desetinné číslo, odhalí se chyba až za běhu a interpret program shodí. Naopak Swift nám nedovolí program ani zkompilovat a na chybu nás upozorní (to je další výhoda kompilace).

Pojďme si nyní něco naprogramovat, ať si nabyté znalosti trochu osvojíme, s teorií budeme pokračovat až příště. Řekněme si nyní tři základní datové typy:

  • Celá čísla: Int
  • Desetinná čísla: Double
  • Textový řetězec: String

Práce s proměnnými

Zkusíme si nadeklarovat celočíselnou proměnnou a, dosadit do ní číslo 56 a "celé" to spustit v Playground. Můžete si založit nový nebo použít ten z předchozí lekce.

var a : Int
a = 56

První příkaz nám nadeklaruje novou proměnnou a datového typu Int. Proměnná tedy bude sloužit pro ukládání celých čísel. Druhý příkaz provádí přiřazení do proměnné, slouží k tomu operátor "rovná se" (=). Mohli bychom to zkrátit a vše provést v jednom kroku.

var a = 56

Kompilátor sám pozná, že hodnotě 56 nejlépe odpovídá datový typ Int a na pozadí ho doplní. Samozřejmě byste mohli využít i delší zápis:

var a : Int = 56
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Ve Swiftu se ale většinu času datové typy takto nespecifikují. Pro desetinnou proměnnou by kód vypadal takto:

var a : Double

a = 56.6

Je to téměř stejné jako s celočíselným. Jako desetinný oddělovač používáme tečku (.).

var vs. let

Zatím jsme se u proměnných seznámili se slůvkem var, které právě proměnnou označuje. Častěji ale ve světě Swift potkáte podobné slůvko let. To slouží pro deklaraci konstanty, kterou není dále možné modifikovat. Protože v běžném programování je takových hodnot většina, používá se primárně let a var pouze v případě, že plánujete proměnnou měnit. let vám zajistí, že má konstanta vždy hodnotu, kterou jste přiřadili a nestane se vám, že by nějaká část kódu omylem měnila hodnotu vašich proměnných.

Funkčnost let si můžeme snadno ověřit třeba takto:

let a : Int

a = 56

a = 22

Jak můžete vidět, Playground zobrazí chybu, protože není možné měnit hodnotu let konstanty.

Program Papoušek

Minulý program byl poněkud nudný, zkusme nějak reagovat na vstup od uživatele. Napíšeme program papoušek, který bude dvakrát opakovat to, co uživatel napsal. Ještě jsme nezkoušeli z konzole nic načítat, ale je to velmi jednoduché. Zároveň vám nebude stačit Playground ale potřebujete Command Line Tool projekt, který jsme si ukázali již dříve. Slouží k tomu metoda readLine(), která nám vrátí textový řetězec z konzole. Zkusme si napsat následující kód:

print("Ahoj, jsem virtuální papoušek Lóra, rád opakuji!")
print("Napiš něco: ")

var vstup : String
vstup = readLine()!

var vystup : String
vystup = vstup + ", " + vstup + "!"

print(vystup)

To už je trochu zábavnější :) První dva řádky jsou jasné, dále deklarujeme textový řetězec vstup. Do vstup se přiřadí hodnota z metody readLine() na konzoli, tedy to, co uživatel zadal. Vykřičník za metodou zatím neřešte, slouží k tomu, abychom nemuseli ověřovat vstup. Pro výstup si pro názornost zakládáme další proměnnou typu textový řetězec. Zajímavé je, jak do vystup přiřadíme, tam využíváme tzv. konkatenace (spojování) řetězců. Pomocí operátoru + totiž můžeme spojit několik textových řetězců do jednoho a je jedno, jestli je řetězec v proměnné nebo je explicitně zadán v uvozovkách ve zdroj. kódu. Do proměnné tedy přiřadíme vstup, dále čárku, znovu vstup a poté vykřičník. Proměnnou vypíšeme a skončíme.

Ahoj, jsem virtuální papoušek Lóra, rád opakuji!
Napiš něco:
Nazdar ptáku
Nazdar ptáku, Nazdar ptáku!

Do proměnné můžeme přiřazovat již v její deklaraci, můžeme tedy nahradit:

var vstup : String
vstup = readLine()!

za

let vstup = readLine()!

Program by šel zkrátit ještě více v mnoha ohledech. Obecně je ale lepší používat více proměnných a dodržovat přehlednost, než psát co nejkratší kód a po měsíci zapomenout, jak vůbec funguje.

Program zdvojnásobovač

Zdvojnásobovač si vyžádá na vstupu číslo a to poté zdvojnásobí a vypíše. Asi bychom s dosavadními znalostmi napsali něco takového:

print("Zadejte číslo k zdvojnásobení:")
var a : Int = readLine()!
a = a * 2
print(a)

Všimněte si zdvojnásobení čísla a, které jsme provedli pomocí přiřazení. Swift nám nyní vyhubuje a podtrhne řádek, ve kterém se snažíme hodnotu z konzole dostat do proměnné typu Int. Narážíme na typovou kontrolu, konkrétně nám readLine() vrací String a my se ho snažíme uložit do Int. Cokoli přijde z textové konzole je vždy text a to i když zadáme číslo. Budeme ho potřebovat tzv. naparsovat.

Parsování

Parsováním se myslí převod z textové podoby na nějaký specifický typ, např. číslo. Často totiž od uživatele či nějaké služby dostanete data jako String, ale vy pro výpočty a podobně potřebujete například Int nebo Double. Parsování je ve Swift velmi jednoduché, má ale zásadní ale, o kterém si krátce povíme níže. Pokud budeme chtít naparsovat např. Int ze String, budeme postupovat takto:

var a = Int("343")

Vidíme, že datový typ Int nabízí konstruktor (metoda vytvářející konkrétní proměnou, resp. objekt, ale o tom později), který bere jako parametr textový řetězec a vytvoří číslo. Využijeme této znalosti v našem programu:

print("Zadejte číslo k zdvojnásobení:")
let vstup = readLine()!
var a = Int(vstup)! // případně Double
a = a * 2
print(a)

Obdobně bychom postupovali i v případě, že by se zadávala desetinná čísla, tedy var a = Double(vstup)!.

Parsování se samozřejmě nemusí povést, když bude v textu místo čísla např. "slovo". Zatím budeme psát za parsovací funkce vykřičníky, stejně jako za všechny funkce, které se nemusejí povést. Podrobněji si problematiku vysvětlíme v následujících lekcích.

Jednoduchá kalkulačka

Ještě jsme nepracovali s desetinnými čísly, zkusme si napsat slibovanou kalkulačku. Bude velmi jednoduchá, na vstup přijdou dvě čísla, program poté vypíše výsledky pro sčítání, odčítání, násobení a dělení.

print("Vítejte v kalkulačce")
print("Zadejte první číslo:")
let a = Double(readLine()!)!
print("Zadejte druhé číslo:")
let b = Double(readLine()!)!
let soucet = a + b
let rozdil = a - b
let soucin = a * b
let podil = a / b
print("Součet: \(soucet)")
print("Rozdíl: \(rozdil)")
print("Součin: \(soucin)")
print("Podíl: \(podil)")
print("Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.")

Výstup:

Konzolová aplikace
Vítejte v kalkulačce
Zadejte první číslo:
3.14
Zadejte druhé číslo:
2.72
Součet: 5.86
Rozdíl: 0.42
Součin: 8.5408
Podíl: 1.15441176470588
Děkuji za použití kalkulačky, aplikaci ukončíte libovolnou klávesou.

Všimněte si dvou věcí. Zaprvé jsme zjednodušili parsování z konzole tak, abychom nepotřebovali stringovou proměnnou, protože bychom ji stejně již poté nepoužili. Zadruhé na konci programu potřebujeme vypsat čísla, protože ale funkce print() vyžaduje typ String, "obalíme" naše čísla (či cokoliv jiného) do \(). Tato praktika se nazývá String Interpolation (interpolace řetězců) a na pozadí zkrátka dojde k vyhodnocení výrazu v \(). Klidně byste zde mohli číslo ještě třeba vynásobit či dále upravit. Viz níže.

print("Součet: \(a + b)")

V následujícím cvičení, Řešené úlohy k 1.-2. lekci Swift, si procvičíme nabyté zkušenosti z předchozích lekcí.


 

Stáhnout

Staženo 44x (134.04 kB)
Aplikace je včetně zdrojových kódů v jazyce Swift

 

Předchozí článek
Úvod do jazyka Swift, platformy a Xcode
Všechny články v sekci
Základní konstrukce jazyka Swift
Článek pro vás napsal Filip Němeček
Avatar
Jak se ti líbí článek?
5 hlasů
Autor se věnuje vývoji iOS aplikací (občas macOS) či těch webových ve frameworku Django. Twitter: @nemecek_f | GitHub nemecek-filip - mrkněte na veřejné projekty
Aktivity (18)

 

 

Komentáře
Zobrazit starší komentáře (14)

Avatar
Filip Němeček
Překladatel
Avatar
Filip Němeček:11.11.2018 22:39

Ahoj, už mi je to jasné. Problém je Playground. Na načítání hodnot je třeba Command Line Tool, jak je napsané u Papouška: "Zároveň vám nebude stačit Playground ale potřebujete Command Line Tool projekt".

Upravím tutoriál, aby to bylo zopakované ještě u té kalkulačky :-)

 
Odpovědět
11.11.2018 22:39
Avatar
Tomas Sindelar Jr.:4.3.2019 18:30

Dobrý den, chtěl bych se zeptat jak se dá uložit "Command line tool project" abych ho mohl někomu poslat, bez vypsaného zdrojového kódu. Děkuji

 
Odpovědět
4.3.2019 18:30
Avatar
Filip Němeček
Překladatel
Avatar
Odpovídá na Tomas Sindelar Jr.
Filip Němeček:4.3.2019 20:12

Ahoj, v Xcode vyber v menu programu Product -> Archive. Otevře se nové okno s vybraným projektem, kde je velké tlačítko Distribute Content. Stačí nechat vybrané Built Products a zvolit, kam se má hotový program exportovat. Pak ho stačí dvojklikem spustit a otevře se Terminal.

 
Odpovědět
4.3.2019 20:12
Avatar
Patrik Endršt:3.6.2019 17:43

Při vypisování výsledků kalkulačky je v návodu toto print("Součet: \(soucet)"), pokud použiju: "Print("Součet: ", soucet)". bude to potom fungovat stejne? Nebo je potřeba výsledek obalit (Interpolovat)? Děkuji.

 
Odpovědět
3.6.2019 17:43
Avatar
Filip Němeček
Překladatel
Avatar
Odpovídá na Patrik Endršt
Filip Němeček:3.6.2019 17:56

Obě varianty budou fungovat stejně. print není moc vybíravé a používá tzv. variadické parametry, takže jich je možné zadat libovolný počet a postupně je vypíše.

 
Odpovědět
3.6.2019 17:56
Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!
Avatar
Odpovídá na Filip Němeček
Patrik Endršt:3.6.2019 18:00

Ok, děkuji. Nebyl jsem si jistý, jestli bude možné s čísly dál pracovat, pokud je tam vložím bez obalení.

 
Odpovědět
3.6.2019 18:00
Avatar
Michal Blahuta:8.8.2019 23:09

Zdravím, mám dotaz, může mi někdo vysvětlit jak funguje ten readLine() jak ho mám přepsat na číslo nebo cokoli? napr:
print("Zadejte první číslo")
let a = Double(readLi­ne()!)! , co tam mom dosadit, nebo vymazat, nebo nějakej novej vzoreček..

 
Odpovědět
8.8.2019 23:09
Avatar
Filip Němeček
Překladatel
Avatar
Odpovídá na Michal Blahuta
Filip Němeček:9.8.2019 8:15

Ahoj, readLine() načítá vlastně všechen vstup od uživatele jako String do doby, než uživatel potvrdí zadání přes Enter. My neošetřujeme chybné vstupy a spoléháme, že zadaný String půjde převést na číslo Double. Double má konstruktor očekávající právě String. Pokud je String třeba “12” nebo “43,857” tak je toto číslo převedeno na typ Double a dá se s ním počítat.

 
Odpovědět
9.8.2019 8:15
Avatar
M4RtY
Člen
Avatar
M4RtY:30. ledna 12:30

Mel bych maly dotaz v pouziti vypisu hodnot ve funkci print(). Zde se pise o metode String Interpolation, a muj dotaz zni, co je praktictejsi pouzit, nebo spis co je ustalenejsi a pouziva se zbezne, jelikoz me napadlo vypsat hodnoty takto:

print("Soucet: " + String(sum))
 
Odpovědět
30. ledna 12:30
Avatar
Filip Němeček
Překladatel
Avatar
Odpovídá na M4RtY
Filip Němeček:30. ledna 13:17

Mně vyhovuje String Interpolation kvůli přehlednosti + nedochází k alokaci "mezi-Stringu" při použití, ale klidně používej, co ti vyhovuje. Když totiž budeš řetězit stringy přes "+", tak vždy dojde k vytvoření řetěžce kvůli každému +..

 
Odpovědět
30. ledna 13:17
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 10 zpráv z 24. Zobrazit vše