Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 3 - Typový systém podruhé: Datové typy ve Swift

V předešlém cvičení, Řešené úlohy k 1.-2. lekci Swift, jsme si procvičili nabyté zkušenosti z předchozích lekcí.

Nyní se na datové typy podíváme více zblízka a vysvětlíme si, kdy jaký použít. Dnešní lekce bude hodně teoretická, ale o to více bude praktická ta příští. Na konci si vytvoříme pár jednoduchých ukázek.

Swift rozeznává dva druhy datových typů, hodnotové a referenční. Těm referenčním se budeme věnovat později.

Hodnotové datové typy

Proměnné hodnotového datového typu si dokážeme jednoduše představit. Může se jednat např. o číslo nebo znak. V paměti je jednoduše uložena přímo hodnota a my k této hodnotě můžeme z programu přímo přistupovat. Slovo přímo jsem tolikrát nepoužil jen náhodou. V tomto Swift kurzu se budeme věnovat výhradně těmto proměnným.

Celočíselné datové typy

Podívejme se nyní na tabulku všech vestavěných celočíselných datových typů ve Swift, všimněte si typu Int, který již známe z minula.

Datový typ Rozsah Velikost
Int -2 147 483 648 až 2 147 483 647 32 bitů
UInt 0 až 4 294 967 295 32 bitů

Rozsahy těchto typů si samozřejmě nemusíte pamatovat, pro celá čísla můžete jednoduše používat vždy typ Int.

Více informací můžete nalézt v oficiální dokumentaci. Tu otevřete skrze Help -> Developer Documentation. Pak už stačí jen vyhledávat. Ke konkrétním datovým typům apod. se můžete snadno dostat skrze Quick Help inspektor v pravé straně Xcode. Stačí mít označený např. Int typ a v inspektoru kliknout na Structure Reference.

Prefix U u UInt znamená, že neumožňuje uložit zápornou hodnotu a tím pádem může uložit dvojnásobnou kladnou. Těmto typům se říká unsigned, klasickým signed.

Desetinná čísla

U desetinných čísel je situace podobná, máme na výběr dva datové typy. Samozřejmě se liší opět v rozsahu hodnoty, dále však ještě v přesnosti (vlastně počtu des. míst). Typ Double má již dle názvu dvojnásobnou přesnost oproti Float.

Datový typ Rozsah Přesnost
Float +-1.5 * 10−45 až +-3.4 * 1038 7 čísel
Double +-5.0 * 10−324 až +-1.7 * 10308 15-16 čísel

Vzhledem k tomu, že desetinná čísla jsou v počítači uložena ve dvojkové soustavě, dochází k určité ztrátě přesnosti. Odchylka je sice téměř zanedbatelná, nicméně když budete programovat např. finanční systém, nepoužívejte tyto dat. typy pro uchování peněz, mohlo by dojít k malým odchylkám.

Typ Double je pro desetinná čísla výchozí, Float je tak nutné blíže specifikovat.

let f : Float = 3.14
let d = 2.72

Jako desetinný separátor používáme ve zdrojovém kódu vždy tečku, nehledě na to, jaké máme v macOS regionální nastavení.

Další vestavěné datové typy

Podívejme se na další datové typy, které nám Swift nabízí:

Datový typ Rozsah Velikost/Přesnost
Character U+0000 až U+ffff 16 bitů
Decimal +-1.0 * 10−28 až +-7.9 * 1028 28-29 čísel
Bool true nebo false 8 bitů

Character

Character nám reprezentuje jeden znak, na rozdíl od String, který reprezentoval celý řetězec hodnot typu Character. Znaky v Swift píšeme do klasických uvozovek a datový typ je nutné specifikovat, jinak bude použit String:

let c : Character = "A"

Decimal

Typ Decimal řeší problém ukládání desetinných čísel v binární podobě, ukládá totiž číslo vnitřně podobně jako text. Používá se tedy pro uchování peněžních hodnot. Ke všem dalším matematickým operacím s des. čísly použijeme Double nebo Float. K zápisu Decimal hodnoty opět musíme datový typ specifikovat:

let number : Decimal = 3.14159265358979323846

Bool

Datový typ Bool nabývá dvou hodnot: true (pravda) a false (nepravda). Budeme ho používat zejména tehdy, až se dostaneme k podmínkám. Do proměnné typu Bool lze uložit jak přímo hodnotu true/false, tak i logický výraz. Zkusme si jednoduchý příklad:

let b = false
let vyraz = 15 > 5
print(b)
print(vyraz)

Výstup programu:

false
true

Výrazy můžeme psát do závorek. To se hodí v případě, že jich máme např. několik. Vidíme, že výraz nabývá hodnoty true (pravda), protože 15 je opravdu větší než 5. Od výrazů je to jen krok k podmínkám, na ně se podíváme příště.

String

Datový typ, se kterým se setkáte na každém kroku. Reprezentuje řetězec znaků, či prostě jakýkoliv text. Jedná se o hodnotový typ. My si ukážeme hlavně důležité metody, které je dobré znát nebo alespoň vědět, že existují. Metody zkoušejte v Command Line, ne v Playground.

contains(), hasSuffix() a hasPreffix()

Můžeme se jednoduše zeptat, zda řetězec začíná, končí nebo zda obsahuje určitý podřetězec (substring). Podřetězcem myslíme část původního řetězce. Všechny tyto metody budou jako parametr brát samozřejmě podřetězec a vracet hodnoty typu Bool (true/false). Zatím na výstup neumíme reagovat, ale pojďme si ho alespoň vypsat:

let s = "Krokonosohroch"
print(s.hasPrefix("krok"))
print(s.hasSuffix("hroch"))
print(s.contains("nos"))
print(s.contains("roh"))

Výstup programu:

false
true
true
false

Vidíme, že vše funguje podle očekávání. První výraz samozřejmě neprošel díky tomu, že řetězec ve skutečnosti začíná velkým písmenem.

uppercased() a lowercased()

Rozlišování velkých a malých písmen může být někdy na obtíž. Mnohdy se budeme potřebovat zeptat na přítomnost podřetězce tak, aby nezáleželo na velikosti písmen. Situaci můžeme vyřešit pomocí metod uppercased() a lowercased(), které vrací řetězec ve velkých a v malých písmenech. Uveďme si reálnější příklad než je Krokonosohroch. Budeme mít v proměnné řádek konfiguračního souboru, který psal uživatel. Jelikož se na vstupy od uživatelů nelze spolehnout, musíme se snažit eliminovat možné chyby, zde např. s velkými písmeny.

var konfig = "Fullscreen shaDows autosave"
konfig = konfig.lowercased()
print("Poběží hra ve fullscreenu?")
print(konfig.contains("fullscreen"))
print("Budou zapnuté stíny?")
print(konfig.contains("shadows"))
print("Přeje si hráč vypnout zvuk?")
print(konfig.contains("nosound"))
print("Přeje si hráč hru automaticky ukládat?")
print(konfig.contains("autosave"))

Výstup programu:

Poběží hra ve fullscreenu?
true
Budou zapnuté stíny?
true
Přeje si hráč vypnout zvuk?
false
Přeje si hráč hru automaticky ukládat?
true

Vidíme, že jsme schopni zjistit přítomnost jednotlivých slov v řetězci tak, že si nejprve řetězec převedeme celý na malá písmena (nebo na velká) a potom kontrolujeme přítomnost slova jen malými (nebo velkými) písmeny. Takhle by mimochodem mohlo opravdu vypadat jednoduché zpracování nějakého konfiguračního skriptu.

trimmingCharacters()

Problémem ve vstupech od uživatele může být i diakritika. Swift ale naštěstí pracuje plně v Unicode, nestane se nám tedy, že by se diakritika nějak zkomolila. Další nástrahou mohou být mezery a obecně všechny tzv. bílé znaky, které nejsou vidět, ale mohou nám uškodit. Obecně může být dobré tzv. trimovat všechny vstupy od uživatele. Máme dostupnou metodu trimmingCharacters(in: ), přičemž je ještě nutné zadat, co budeme trimovat, protože se jedná o výčet, tak napíšeme . a Xcode nám samo navrhne hromadu možností, co trimmovat. Nejčastěji budete používat možnost .whitespacesAndNewlines, což odstraní všechny bílé znaky a také odřádkování okolo řetězce.

print("Zadejte číslo:")
let s = readLine()!
print("Zadal jste text: " + s)
print("Text po funkci trim: " + s.trimmingCharacters(in: .whitespacesAndNewlines))
let a = Int(s)!
print("Převedl jsem zadaný text na číslo parsováním, zadal jste: \(a)")

replacingOccurrences()

Asi nejdůležitější metodou na String je nahrazení určité jeho části jiným textem. Jako parametry zadáme dva podřetězce, jeden co chceme nahrazovat a druhý ten, kterým to chceme nahradit. Metoda vrátí nový String, ve kterém proběhlo nahrazení. Když daný podřetězec metoda nenajde, vrátí původní řetězec. Zkusme si to:

let s = "Java je nejlepší!"
let replaced = s.replacingOccurrences(of: "Java", with: "Swift")
print(replaced)

Výstup programu:

Swift je nejlepší!

Iterpolace řetězců

Interpolaci řetězců jsme si již zmiňovali. Ve Swift argumenty či jednoduše proměnné, které chceme do řetězce na určitá místa vložit, zapíšeme přímo do stringu pomocí \():

let a = 10
let b = 20
let c = a + b
let s = "Když sečteme \(a) a \(b), dostaneme \(c)"
print(s)

Výstup programu:

Když sečteme 10 a 20, dostaneme 30

Funkce print() sama umí přijímat text v takovémto formátu, můžeme tedy napsat:

let a = 10
let b = 20
let c = a + b
print("Když sečteme \(a) a \(b), dostaneme \(c)")

Toto je velmi užitečná a přehledná cesta, jak sestavovat řetězce. Pokud chceme vypsat čísla, tak se ji nevyhnete. U více Stringů můžete použít konkatenaci (jednoduše + pro jejich "sečtení").

Vlastnost count

Poslední, ale nejdůležitější vlastnost (pozor, ne metoda) je count, tedy počet znaků. Vrací celé číslo, které představuje počet znaků v řetězci. Za vlastnosti nepíšeme závorky, protože nemají parametry. Slovo "length" by dávalo intuitivně větší smysl, ale Swift vlastnost bere jako zmiňovaný počet znaků, takže si holt musíme zvyknout na count.

print("Zadejte vaše jméno:")
let jmeno = readLine()!
print("Délka vašeho jména je: \(jmeno.count)")

Padding

Padding znamená, že Stringu přidáme znaky, abychom ho dostali na požadovanou délku. Často se používá pro přidání mezer, ale můžete doplnit jakýkoliv znak. Některé jazyky nabízí pohodlné metody pro padding zleva nebo zprava. Swift má pouze jednu a chce po nás celkem dost parametrů. Podrobně si ji popíšeme dále v kurzu.

Pokud vám nějaké metody z této lekce nefungují, ujistěte se, že máte v souboru import Foundation pro importování základní Swift funkcionality.

Je toho ještě spoustu k vysvětlování a jsou další datové typy, které jsme neprobrali.

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


 

Předchozí článek
Řešené úlohy k 1.-2. lekci Swift
Všechny články v sekci
Základní konstrukce jazyka Swift
Přeskočit článek
(nedoporučujeme)
Řešené úlohy k 3. lekci Swift
Článek pro vás napsal Filip Němeček
Avatar
Uživatelské hodnocení:
19 hlasů
Autor se věnuje vývoji iOS aplikací (občas macOS)
Aktivity