Další informace o základních datových typech
Go je jazyk silného typu . Každá proměnná, kterou deklarujete, je svázaná s konkrétním datovým typem a bude přijímat pouze hodnoty, které odpovídají danému typu.
V Go máte čtyři kategorie datových typů:
- Základní typy: čísla, řetězce a logické hodnoty
- Agregační typy: pole a struktury
- Odkazové typy: ukazatele, řezy, mapy, funkce a kanály
- Typy rozhraní: rozhraní
V tomto modulu pokrýváme pouze základní typy. Nemějte obavy, pokud nevíte, jaké jsou ostatní typy. Probereme je v nadcházejících modulech.
Začněme prozkoumáním číselných datových typů.
Celočíselná čísla
Obecně platí, že klíčové slovo pro definování celočíselného typu je int
. Ale Go také poskytuje int8
, , int16
int32
a int64
typy, které jsou inty s velikostí 8, 16, 32 nebo 64 bitů, v uvedeném pořadí. Pokud používáte 32bitový operační systém, int
je velikost obvykle 32 bitů. V 64bitových systémech int
je velikost obvykle 64 bitů. Toto chování se ale může lišit od jednoho počítače k druhému. Můžete použít uint
. Tento typ však použijte pouze v případě, že potřebujete z určitého důvodu reprezentovat hodnotu jako číslo bez znaménka. Go také poskytuje uint8
, uint16
, uint32
a uint64
typy.
Tady je příklad použití různých celočíselného typu v Go:
var integer8 int8 = 127
var integer16 int16 = 32767
var integer32 int32 = 2147483647
var integer64 int64 = 9223372036854775807
fmt.Println(integer8, integer16, integer32, integer64)
Ve většině případů budete používat int
, ale potřebujete vědět o ostatních celočíselné typy, protože v Go int
není totéž jako int32
, i když je celé číslo přirozené velikosti 32 bitů. Jinými slovy, budete muset explicitně přetypovat, když se vyžaduje přetypování. A pokud se pokusíte provést matematickou operaci mezi různými typy, zobrazí se chyba. Předpokládejme například, že máte tento kód:
var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(integer16 + integer32)
Při spuštění programu se zobrazí tato chyba:
invalid operation: integer16 + integer32 (mismatched types int16 and int32)
Jak vidíte, při převodu hodnoty z jednoho typu na jiný v Go je nutné explicitně uvést nový typ. Na konci tohoto modulu si řekneme, jak správně přetypovat typy.
Při učení Go můžete slyšet o spuštěních. A rune
je jednoduše alias pro int32
datový typ. Používá se k reprezentaci znaku Unicode (nebo bodu kódu Unicode). Předpokládejme například, že máte následující kód:
rune := 'G'
fmt.Println(rune)
Při spuštění předchozího fragmentu kódu můžete očekávat, že se program vytiskne G
na příkazovém řádku. Ale uvidíte číslo 71
, které představuje znak Unicode pro G
. Budeme mluvit o runech v nadcházejících modulech.
Informace o rozsazích jednotlivých typů najdete ve zdrojovém kódu Jazyka Go. Znalost rozsahů jednotlivých typů vám pomůže vybrat správný datový typ a vyhnout se také plýtvání bity v paměti.
Výzva 1
Nastavte jinou proměnnou typu int
a použijte hodnotu z integer32
proměnné nebo integer64
proměnné k potvrzení přirozené velikosti proměnné ve vašem systému. Pokud používáte 32bitový systém a používáte hodnotu vyšší než 2 147 483 647, zobrazí se chyba přetečení, která vypadá takto: constant 9223372036854775807 overflows int
Řešení výzvy:
package main import "fmt" func main() { var integer32 int = 2147483648 fmt.Println(integer32) }
Výzva 2
Deklarujte proměnnou bez znaménka jako uint
a inicializovat ji zápornou hodnotou, například -10
. Při pokusu o spuštění programu by se měla zobrazit chyba podobná této: constant -10 overflows uint
.
Řešení výzvy:
package main import "fmt" func main() { var integer uint = -10 fmt.Println(integer) }
Čísla s plovoucí desetinou čárkou
Go poskytuje datové typy pro dvě velikosti čísel s plovoucí desetinou čárkou: float32
a float64
. Tyto typy můžete použít, když potřebujete uložit velká čísla a nevejdou se do žádného z výše uvedených celočíselného typu. Rozdíl mezi těmito dvěma typy je maximální velikost bitů, které mohou obsahovat. Na následujících řádcích se dozvíte, jak používat tyto dva typy:
var float32 float32 = 2147483647
var float64 float64 = 9223372036854775807
fmt.Println(float32, float64)
Limity těchto dvou typů najdete pomocí math.MaxFloat32
konstant, math.MaxFloat64
které jsou k dispozici v math
balíčku. K vytištění maximálních hodnot s plovoucí desetinou čárkou na příkazovém řádku použijte následující kód:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(math.MaxFloat32, math.MaxFloat64)
}
Typy s plovoucí desetinnou čárkou jsou užitečné také v případě, že potřebujete použít desetinná čísla. Můžete například napsat něco jako tento kód:
const e = 2.71828
const Avogadro = 6.02214129e23
const Planck = 6.62606957e-34
Všimněte si, že s předchozím kódem Go odvodí datové typy z použitých hodnot.
Logické hodnoty
Logický typ má pouze dvě možné hodnoty: true
a false
. Deklarujete logický typ pomocí klíčového slova bool
. Jazyk Go se liší od jiných programovacích jazyků. V Go nemůžete implicitně převést logický typ na 0 nebo 1. Musíte to udělat explicitně.
Můžete tedy deklarovat logickou proměnnou takto:
var featureFlag bool = true
Když mluvíme o příkazech toku řízení v Go, použijeme v nadcházejícím modulu logické datové typy. Použijeme je také v pozdějších modulech.
Řetězce
Nakonec se podíváme na nejběžnější datový typ v libovolném programovacím jazyce: string. V jazyce Go se klíčové slovo string
používá k reprezentaci datového typu řetězce. Pokud chcete inicializovat řetězcovou proměnnou, musíte její hodnotu definovat v uvozovkách ("
). Jednoduché uvozovky ('
) se používají pro jednotlivé znaky (a pro běhy, jak jsme viděli v předchozí části).
Následující kód například ukazuje dva způsoby, jak deklarovat a inicializovat řetězcovou proměnnou:
var firstName string = "John"
lastName := "Doe"
fmt.Println(firstName, lastName)
Někdy budete potřebovat řídicí znaky. To uděláte tak, že před znakem použijete zpětné lomítko (\
). Tady jsou například nejběžnější příklady použití řídicích znaků:
\n
pro nové řádky\r
pro návrat na začátek řádku\t
pro karty\'
pro jednoduché uvozovky\"
pro dvojité uvozovky\\
pro zpětné lomítka
Pomocí následujícího fragmentu kódu otestujte řídicí znaky:
fullName := "John Doe \t(alias \"Foo\")\n"
fmt.Println(fullName)
Měl by se zobrazit následující výstup (včetně nového řádku):
John Doe (alias "Foo")
Výchozí hodnoty
Zatím jsme ji téměř pokaždé, když jsme deklarovali proměnnou, inicializovali jsme ji hodnotou. Ale na rozdíl od jiných programovacích jazyků mají všechny datové typy výchozí hodnotu, pokud proměnnou neicializujete. Tato funkce je praktická, protože před použitím proměnné nemusíte kontrolovat, jestli byla proměnná inicializována.
Tady je seznam několika výchozích hodnot pro typy, které jsme zatím prozkoumali:
0
proint
typy (a všechny jeho podtypy, napříkladint64
)+0.000000e+000
profloat32
afloat64
typyfalse
probool
typy- Prázdná hodnota pro
string
typy
Spuštěním následujícího fragmentu kódu potvrďte výchozí hodnoty uvedené dříve:
var defaultInt int
var defaultFloat32 float32
var defaultFloat64 float64
var defaultBool bool
var defaultString string
fmt.Println(defaultInt, defaultFloat32, defaultFloat64, defaultBool, defaultString)
Kód podobný tomuto kódu můžete použít k určení výchozí hodnoty pro datový typ, který jsme tady neprozkoumali.
Převody typů
V předchozí části jsme potvrdili, že implicitní přetypování nefunguje v Go. V Go je potřeba přetypování provést explicitně. Go nabízí několik nativních způsobů převodu jednoho datového typu na jiný datový typ. Jedním ze způsobů je například použití integrované funkce pro každý typ, například takto:
var integer16 int16 = 127
var integer32 int32 = 32767
fmt.Println(int32(integer16) + integer32)
Dalším přístupem k přetypování v Go je použití balíčku strconv. Chcete-li například převést objekt string
na int
a naopak, můžete použít tento kód:
package main
import (
"fmt"
"strconv"
)
func main() {
i, _ := strconv.Atoi("-42")
s := strconv.Itoa(-42)
fmt.Println(i, s)
}
Spusťte předchozí kód a ověřte, že se spustí a vytiskne -42
dvakrát.
Všimněte si, že jako název proměnné v předchozím kódu se používá podtržítko (_
). V Go znamená, _
že nebudeme tuto hodnotu proměnné používat a že ji chceme ignorovat. Jinak program nebude kompilovat, protože musíme použít všechny proměnné, které deklarujeme. Vrátíme se k tomuto tématu a dozvíte se, co _
obvykle představuje v nadcházejících modulech.