Перейти до змісту

Базові (зумовлені) типи

Go постачається з фіксованим невеликим набором вбудованих типів. Жодних інших примітивних типів не існує — все інше будується з цих.

Цілі числа

Фіксованого розміру

var a int8   = -128                          // -128 .. 127
var b int16  = 32_000                        // _ дозволяється як роздільник цифр
var c int32  = 2_000_000_000                 // до ~2,1×10⁹
var d int64  = 9_000_000_000_000_000_000     // до ~9,2×10¹⁸

var u uint8  = 255                           // 0 .. 255
var v uint16 = 65_535
var w uint32 = 4_000_000_000                 // до ~4,3×10⁹
var x uint64 = 18_000_000_000_000_000_000    // до ~1,8×10¹⁹

Залежні від архітектури

var n int        // 32 або 64 біти відповідно до платформи
var u uint       // те саме, що int, але без знаку
var p uintptr    // достатньо великий для зберігання сирого значення вказівника

int — це не псевдонім int64. Навіть на 64-бітній машині, де вони мають однаковий розмір, це різні типи — дивіться 03-type-conversions.md.

Псевдоніми

Існують два псевдоніми цілих чисел:

byte == uint8        // byte для сирих байтових даних
rune == int32        // rune для кодових точок Unicode

Використовуйте byte при роботі з бінарними даними ([]byte) і rune — при роботі з символами рядка.

Числа з рухомою комою

var f32 float32 = 1.5e3
var f64 float64 = 3.14159265358979

Обидва відповідають стандарту IEEE 754. float64 є типом за замовчуванням для нетипізованих констант з рухомою комою і використовується в 99% випадків. Не вживайте float32 без зваженої причини (розкладка в пам'яті, GPU-буфери тощо).

У стандартній бібліотеці немає десяткових типів — якщо потрібна точна десяткова арифметика (наприклад, для грошей), зверніться до github.com/shopspring/decimal або подібного пакету.

Комплексні числа

var z complex128 = 1 + 2i
fmt.Println(real(z), imag(z))    // 1 2

Потрібні рідко — більшість коду може ігнорувати complex64 / complex128.

Булевий тип

var ok bool = true
var done bool          // false (нульове значення)

bool не перетворюється на int. Не можна писати if 1 { ... } або if someInt { ... } — це помилка компіляції. Умова в if/for обов'язково повинна бути bool.

var n int = 1
if n {                  // compile error: non-bool n (type int) used as if condition
    fmt.Println("nope")
}

if n != 0 {             // ok
    fmt.Println("yep")
}

З досвіду Python: немає істинності/хибності. Порожні рядки, порожні зрізи, нуль і nil не є неявно хибними. Завжди пишіть явне порівняння.

Рядок

var greeting string = "hello, 世界"
fmt.Println(len(greeting))         // 13 — кількість БАЙТІВ, а не символів!
fmt.Println(greeting[0])           // 104 — байт 'h'

("hello, " — це 7 ASCII-байтів; та — по 3 UTF-8 байти кожен.)

Два неочевидні факти:

  1. Рядки незмінні. Не можна робити s[0] = 'H' — помилка компіляції.
  2. len(s) — це байти, а не символи. Оскільки рядки Go кодуються в UTF-8, один символ на кшталт може займати 3 байти. Щоб підрахувати символи (руни):
import "unicode/utf8"

s := "世界"
fmt.Println(len(s))                       // 6 (байти)
fmt.Println(utf8.RuneCountInString(s))    // 2 (руни)

Для перебору по рунах використовуйте range:

for i, r := range "hi世" {
    fmt.Printf("byte index %d, rune %c (%d)\n", i, r, r)
}
// output:
// byte index 0, rune h (104)
// byte index 1, rune i (105)
// byte index 2, rune 世 (19990)

З досвіду Python: рядки Python 3 — це послідовності кодових точок Unicode; s[0] для "世" повертає "世". Рядки Go — це байтові послідовності, інтерпретовані як UTF-8; s[0] для "世" повертає перший байт, а не перший символ.

Нетипізовані константи — коротке введення

Константи можуть бути нетипізованими аж до моменту використання.

const small = 10        // нетипізована цілочисельна константа

var a int     = small   // ok — small стає int
var b int64   = small   // ok — small стає int64
var c float64 = small   // ok — small стає float64

Якби ви написали const small int = 10, скомпілювався б лише перший рядок. Саме нетипізовані константи дозволяють писати x := 1.5 і отримувати float64 без зайвих дій.

Типи за замовчуванням, якщо контекст вимагає конкретного типу:

Форма константи Тип за замовчуванням
ціле число (42, 0x2a) int
число з рухомою комою (3.14, 1e10) float64
руна ('A') rune (тобто int32)
рядок ("hi") string
булеве (true) bool
комплексне (2i) complex128

Що не є вбудованим типом

Речі, які Python-розробник може очікувати, але яких не існує:

  • Немає ключових слів list / dict / set — є slice, map, вбудованого множини немає (використовуйте map[T]struct{}).
  • Немає tuple — використовуйте множинне повернення або структуру.
  • Немає decimalfloat64 або сторонній модуль.
  • Немає ключового слова bigint — використовуйте math/big.Int.
  • Немає None — використовуйте nil (дійсний лише для вказівника, зрізу, мапи, каналу, функції, інтерфейсу).

Джерела