Menu

Typy proste w Zero: liczby całkowite, float, bool, String, Void

Wbudowane typy, które Zero daje od razu: liczby całkowite ze znakiem i bez znaku w każdej szerokości, liczby zmiennoprzecinkowe, wartości logiczne, znaki, teksty i pusty typ Void.

Typy wbudowane

Zero daje ci mały, regularny zestaw typów prostych. Nic egzotycznego, nic zaskakującego: tylko te, których potrzebuje każdy język systemowy, nazwane w spójny sposób.

RodzinaTypyUwagi
Liczby całkowite ze znakiemi8, i16, i32, i64Kod uzupełnień do dwóch.
Liczby całkowite bez znakuu8, u16, u32, u64Tylko 0 i wartości dodatnie.
Rozmiar wskaźnikausize, isizeSzerokość zgodna ze wskaźnikiem platformy.
Liczby zmiennoprzecinkowef32, f64IEEE-754.
Wartość logicznabooltrue lub false.
ZnakcharPojedyncza wartość skalarna Unicode.
TekstStringTekst w UTF-8.
PustyVoid"Brak użytecznej wartości".

To pełna lista typów prostych, z których korzystasz na co dzień. Typy złożone (shape, enum, choice) buduje się z nich.

Liczby całkowite

Typy całkowite mają jednolity schemat nazw: i dla typów ze znakiem, u dla typów bez znaku, a potem liczba bitów. i32 to 32-bitowa liczba całkowita ze znakiem, u8 to bajt bez znaku, a i64 to 64-bitowa liczba całkowita ze znakiem.

let small_signed: i8   = -120
let byte:         u8   = 250
let id:           i32  = 1
let big:          i64  = 9_000_000_000
let index:        usize = 0

Domyślnym typem literału bez sufiksu jest i32, chyba że otaczający kontekst wymusza coś innego:

let answer = 42       // i32

Gdy potrzebujesz konkretnej szerokości, dodaj sufiks do literału albo adnotację do wiązania:

let byte = 250_u8     // literał z typem
let byte: u8 = 250    // wiązanie z typem

Obie formy dają tę samą wartość. Forma z sufiksem literału przydaje się, gdy przekazujesz literał bezpośrednio do funkcji albo budujesz strukturę:

let pair: BytePair = Pair { left: 1_u8, right: 2_u8 }

Jaką szerokość wybrać

Krótka reguła:

  • i32 do większości obliczeń ze znakiem. Wystarczająco szeroki dla niemal wszystkiego, co liczysz, i szybki na każdej platformie.
  • u8 do pracy na bajtach. Bajty z pliku, bajty w buforze, bajty przesyłane siecią.
  • u32 / u64 do nieujemnych liczników, gdy liczy się zakres. Przesunięcia w plikach powyżej 2 GB, duże liczniki.
  • usize do rozmiarów i indeksów. Ma rozmiar wskaźnika, czyli odpowiada temu, czego platforma używa do adresowania pamięci.
  • i64 do czasu od epoki i podobnych wartości. Wystarczy na nanosekundy przez setki lat.

Wybór najmniejszego pasującego typu to dobra praktyka; wybór za małego typu i przepełnienie to znacznie większy problem niż typ o jeden bit za szeroki.

Wartości logiczne

let ok = true
let done: bool = false

bool ma dokładnie dwie wartości: true i false. To literały, a nie stałe importowane skądś. Warunek w if lub while jest typu bool: liczby całkowite ani teksty nie mają niejawnej wartości logicznej.

if ok {
    check world.out.write("tak\n")
} else {
    check world.out.write("nie\n")
}

Instrukcje warunkowe szczegółowo omawia artykuł If/else.

Liczby zmiennoprzecinkowe

f32 i f64 to odpowiednio 32-bitowe i 64-bitowe liczby zmiennoprzecinkowe IEEE-754. Używaj ich, gdy potrzebujesz wartości ułamkowych: pomiarów, proporcji, geometrii. Do dokładnych obliczeń na kwotach pieniędzy lepiej użyć liczb całkowitych w najmniejszej jednostce (grosze, satoshi) niż liczb zmiennoprzecinkowych.

let ratio: f32 = 0.5
let pi:    f64 = 3.141592653589793

f64 to domyślny typ literałów zmiennoprzecinkowych bez sufiksu.

Znaki i teksty

char przechowuje pojedynczą wartość skalarną Unicode:

let initial: char = 'Z'

String to ciąg znaków, który biblioteka standardowa zwykle koduje w UTF-8. Literały tekstowe używają podwójnych cudzysłowów:

let message: String = "cześć z zero\n"

Działają typowe sekwencje ucieczki: \n dla nowej linii, \t dla tabulatora, \\ dla dosłownego ukośnika wstecznego, \" dla dosłownego cudzysłowu.

let multi_line = "linia pierwsza\nlinia druga\n"

Biblioteka standardowa udostępnia bajtowe widoki tekstu do pracy niskopoziomowej. Forma std.mem.span("zero") zwraca Span<u8> na bajtach, co przydaje się przy parsowaniu, haszowaniu albo porównywaniu bajt po bajcie.

Void

Void to typ Zero oznaczający "brak użytecznej wartości zwracanej". Używają go funkcje istniejące dla swoich efektów ubocznych:

pub fun main(world: World) -> Void raises {
    check world.out.write("cześć\n")
}

main coś wypisuje i kończy działanie. Nie ma wartości do oddania, więc typem jest Void. Zobaczysz Void przy większości funkcji korzystających z World: wybiera się je dla ich efektu, a nie wyniku.

Podkreślniki w literałach liczbowych

Długie literały liczbowe mogą używać podkreślników jako separatorów wizualnych. Kompilator je ignoruje, więc służą wyłącznie czytelności:

let big   = 9_000_000_000_i64
let bytes = 1_048_576_u32     // 1 MiB

Wstawiaj je wszędzie tam, gdzie cyfry zaczynają być trudne do policzenia.

Ściąga: sufiksy literałów z typem

SufiksTypPrzykład
_i8 / _i16 / _i32 / _i64Liczba całkowita ze znakiem127_i8
_u8 / _u16 / _u32 / _u64Liczba całkowita bez znaku255_u8
_usize / _isizeRozmiar wskaźnika0_usize
_f32 / _f64Liczba zmiennoprzecinkowa0.5_f32

Sięgaj po nie, gdy tworzysz wartość, a otaczający kontekst nie ustala jej typu.

Dalej: funkcje

Typy proste są bezużyteczne, jeśli nie ma co z nimi robić. Następny artykuł omawia funkcje w Zero: jak je deklarować, zwracać z nich wartości i łączyć je w prawdziwe programy.

Najczęściej zadawane pytania

Jakie typy proste ma Zero?

Zero ma liczby całkowite ze znakiem o określonym rozmiarze i8, i16, i32, i64; liczby bez znaku u8, u16, u32, u64; liczby o rozmiarze wskaźnika usize i isize; liczby zmiennoprzecinkowe f32 i f64; bool; char; String; oraz Void dla funkcji, które nie zwracają nic użytecznego.

Jaki jest domyślny typ liczby całkowitej w Zero?

Literał całkowity bez sufiksu, taki jak 42, ma domyślnie typ i32, chyba że kontekst wymusza inny. Aby użyć konkretnej szerokości, zapisz literał z sufiksem, np. 42_u8 lub 42_i64, albo jawnie podaj typ wiązania: let count: u8 = 42.

Czy Zero ma osobny typ tekstowy?

Tak. Literały tekstowe, takie jak "hello", mają wbudowany typ tekstowy, który biblioteka standardowa traktuje jako ciąg bajtów (zwykle UTF-8). Do pracy na niższym poziomie z bajtami biblioteka standardowa udostępnia spany i narzędzia bajtowe; do operacji na znakach służy char dla pojedynczych wartości skalarnych.

Co oznacza Void w Zero?

Void to typ zwracany funkcji, która nie daje użytecznej wartości: istnieje tylko dla swoich efektów ubocznych. Zwyczajowa sygnatura pub fun main(world: World) -> Void raises używa Void, bo main ma wykonać I/O i zakończyć działanie, a nie zwrócić wartość.

Czym różni się i32 od u32 w Zero?

i32 to 32-bitowa liczba całkowita ze znakiem o zakresie od −2 147 483 648 do 2 147 483 647. u32 jest bez znaku i ma zakres od 0 do 4 294 967 295. Używaj typów ze znakiem, gdy wartości ujemne mają sens, a bez znaku, gdy wartość ujemna byłaby błędem: dla liczników, indeksów, rozmiarów i tak dalej.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ