Menu

Typy danych w Go (Golang): int, float64, string, bool, byte, rune

Wbudowane typy Go: rozmiary i zakresy liczb całkowitych, float32 i float64, bool, string, byte i rune, liczby zespolone, wartości zerowe oraz wypisywanie typu wartości przez %T.

Na tej stronie są działające edytory: edytuj, uruchamiaj i od razu zobacz wynik.

Podstawowe typy Go to liczby, wartości logiczne i stringi. Każda zmienna ma dokładnie jeden typ, ustalony w czasie kompilacji, a Go nigdy nie konwertuje typów za ciebie. %T wypisuje typ dowolnej wartości:

Zwróć uwagę, że 'G' wypisuje się jako 71 z typem int32: znak w apostrofach to runa, czyli liczba (punkt kodowy Unicode). rune to alias int32 (ten sam typ pod drugą nazwą), więc %T zgłasza int32. Podobnie byte zgłasza uint8.

Liczby całkowite

TypRozmiarZakres
int88 bitówod -128 do 127
int1616 bitówod -32 768 do 32 767
int3232 bityod około -2,1 miliarda do 2,1 miliarda
int6464 bityod około -9,2 tryliona do 9,2 tryliona
uint8 (byte)8 bitówod 0 do 255
uint1616 bitówod 0 do 65 535
uint3232 bityod 0 do około 4,3 miliarda
uint6464 bityod 0 do około 18,4 tryliona
int, uint32 lub 64 bityrozmiar słowa platformy
uintptrrozmiar platformyprzechowuje wartość wskaźnika, do kodu niskopoziomowego

Domyślnie używaj int. len() zwraca int, indeksy slice'ów to int i liczniki pętli to int. Na każdej platformie 64-bitowej int ma 64 bity. Po typy o określonym rozmiarze sięgaj wtedy, gdy rozmiar jest częścią umowy: int32 w binarnym formacie pliku, uint8 dla surowych bajtów, int64 dla znacznika czasu Unix w nanosekundach.

Unikaj typów bez znaku dla wielkości, które "nie mogą być ujemne", takich jak liczniki. Odejmowanie poniżej zera zawija się do ogromnej liczby, zamiast dać wartość ujemną, którą dałoby się wyłapać.

Limity i przepełnienie

Pakiet math ma stałą dla każdego limitu. W czasie działania arytmetyka całkowita, która się przepełnia, po cichu się zawija:

Bez panic, bez błędu: 127 + 1 staje się -128. W czasie kompilacji sprawdzane są tylko wyrażenia stałe (var b int8 = 128 się nie kompiluje). Jeśli w twoich danych możliwe jest przepełnienie, sprawdzaj przed operacją albo użyj math/big.

Literały całkowite

million := 1_000_000   // underscores for readability (Go 1.13+)
mask := 0xFF           // hexadecimal
perm := 0o755          // octal (also the older form 0755)
flags := 0b1010        // binary

Liczby zmiennoprzecinkowe

TypRozmiarPrecyzja
float3232 bityokoło 6 do 9 cyfr znaczących
float6464 bityokoło 15 do 17 cyfr znaczących

Literał z kropką dziesiętną lub wykładnikiem (2.5, 1e6) jest domyślnie typu float64, a pakiet math przyjmuje i zwraca float64. Używaj go, chyba że liczy się pamięć w dużej tablicy.

Liczby zmiennoprzecinkowe są binarne, więc większość ułamków dziesiętnych to przybliżenia:

Wynikają z tego dwie zasady. Nigdy nie porównuj floatów przez == po obliczeniach. I nigdy nie przechowuj pieniędzy we floatach: użyj liczby całkowitej groszy albo biblioteki liczb dziesiętnych.

Dzielenie floata przez zero daje +Inf, -Inf lub NaN zamiast panic. Dzielenie liczby całkowitej przez zero wywołuje panic w czasie działania (runtime error: integer divide by zero), a stały dzielnik równy zero to błąd kompilacji.

Wartości logiczne

bool przechowuje true lub false, a jego wartość zerowa to false. Go nie traktuje liczb, pustych stringów ani nil jako wartości logicznych. if count {} to błąd kompilacji; napisz if count > 0 {}. Operatory to &&, || i !, przy czym && i || działają skrótowo.

Stringi

string to niezmienny ciąg bajtów, zwykle tekst w UTF-8. len(s) liczy bajty, nie znaki:

é zajmuje w UTF-8 dwa bajty, więc len zgłasza 6 dla pięciu znaków. Stringi w cudzysłowach przetwarzają sekwencje ucieczki, takie jak \n; surowe stringi w odwrotnych apostrofach tego nie robią i mogą obejmować wiele linii. Strona o stringach omawia pakiet strings, a strona o runach i bajtach szczegółowo opisuje UTF-8.

byte i rune

AliasTo samo coPrzechowuje
byteuint8jeden bajt surowych danych
runeint32jeden punkt kodowy Unicode

To aliasy, a nie nowe typy: byte i uint8 są wymienne bez konwersji. Nazwy mówią, co oznacza liczba.

Liczby zespolone

Go ma wbudowane typy zespolone, complex64 i complex128, a do tego real, imag i pakiet math/cmplx:

Potrzebuje ich niewiele programów, ale przetwarzanie sygnałów i część kodu numerycznego tak.

Typy złożone i referencyjne

Typy podstawowe łączą się w typy złożone. Każdy ma własną stronę:

TypPrzykładWartość zerowa
tablica[3]inttrzy zera
slice[]intnil
mapamap[string]intnil
strukturastruct{ X, Y int }każde pole wyzerowane
wskaźnik*intnil
funkcjafunc(int) intnil
kanałchan intnil
interfejserror, anynil

any to alias interface{} (od Go 1.18) i może przechowywać wartość dowolnego typu.

Typy nazwane

Możesz zdefiniować nowy typ na podstawie istniejącego. Ma tę samą reprezentację, ale jest odrębnym typem i może mieć metody:

type Celsius float64
type UserID int64

var t Celsius = 21.5
var f float64 = t // compile error: cannot use t (variable of float64 type Celsius) as float64 value in variable declaration

Ta surowość jest celowa: UserID nie da się przypadkiem przekazać tam, gdzie oczekiwany jest OrderID. Gdy naprawdę tego chcesz, konwertuj jawnie: float64(t). Zasady opisuje strona o konwersji typów, a do przechodzenia między liczbami i stringami służą funkcje z strconv.

Wartości zerowe

Każdy typ ma wartość zerową, czyli to, co zmienna przechowuje, zanim cokolwiek do niej przypiszesz: 0 dla liczb, false dla bool, "" dla stringów oraz nil dla wskaźników, slice'ów, map, kanałów, funkcji i interfejsów. W Go nie ma niezainicjalizowanych zmiennych.

Najczęściej zadawane pytania

Jaki rozmiar ma int w Go?

int i uint mają 64 bity na platformach 64-bitowych (amd64, arm64) i 32 bity na platformach 32-bitowych. Jeśli potrzebujesz stałego rozmiaru, na przykład dla formatu pliku lub protokołu sieciowego, użyj int32, int64, uint8 i tak dalej. Do zwykłych liczników, indeksów i długości używaj int.

Jak wypisać typ zmiennej w Go?

Użyj czasownika %T: fmt.Printf("%T\n", x) wypisuje int, float64, []string, main.User i tak dalej. W kodzie reflect.TypeOf(x) zwraca tę samą informację jako wartość, którą można badać.

Czym różni się byte od rune w Go?

byte to alias uint8 i przechowuje jeden bajt surowych danych. rune to alias int32 i przechowuje jeden punkt kodowy Unicode. String to ciąg bajtów; iterowanie po nim przez for range dekoduje go na runy.

Używać float32 czy float64 w Go?

Używaj float64, chyba że masz powód, żeby tego nie robić. To domyślny typ literałów zmiennoprzecinkowych, typ, z którym pracuje pakiet math, i ma około 15 do 17 cyfr znaczących precyzji wobec około 6 do 9 dla float32. Wybieraj float32 tylko po to, żeby zmniejszyć o połowę zużycie pamięci w dużych tablicach albo dopasować się do zewnętrznego formatu.

Jaka jest maksymalna wartość int w Go?

Użyj stałych z pakietu math: math.MaxInt (9223372036854775807 na platformach 64-bitowych), math.MinInt, math.MaxInt64, math.MaxUint32 i tak dalej. Arytmetyka, która przekracza limit, w czasie działania po cichu się zawija; nie wywołuje panic.

Ilustracja języków programowania w Coddy

Ucz się programowania z Coddy

ZACZNIJ