1 Введение в типы данных языка Go
В языке Go типы данных являются основой программирования, определяя форму данных, которые могут хранить переменные. Основные типы данных, предоставляемые языком Go, в основном разделяются на следующие категории:
Тип данных | Описание | Используемая память |
---|---|---|
bool | Логический тип, используется для хранения true или false | 1 байт |
int, uint | Знаковые и беззнаковые целые числа, размер по умолчанию зависит от платформы системы | 4 или 8 байт |
int8, uint8 | 8-битные знаковые и беззнаковые целые числа | 1 байт |
int16, uint16 | 16-битные знаковые и беззнаковые целые числа | 2 байта |
int32, uint32 | 32-битные знаковые и беззнаковые целые числа | 4 байта |
int64, uint64 | 64-битные знаковые и беззнаковые целые числа | 8 байт |
float32 | 32-битное число с плавающей запятой | 4 байта |
float64 | 64-битное число с плавающей запятой | 8 байт |
complex64 | Комплексное число с 32-битными действительной и мнимой частями | 8 байт |
complex128 | Комплексное число с 64-битными действительной и мнимой частями | 16 байт |
byte | Похож на uint8 | 1 байт |
rune | Похож на int32, представляющий кодовую точку Unicode | 4 байта |
string | Строковый тип | Зависит от длины строки |
error | Интерфейс ошибки, используется для возврата информации об ошибке | Нет фиксированного размера |
Эти типы могут быть выбраны в зависимости от различных потребностей, таких как числовые вычисления, обработка текста или логическое управление.
2 Типы данных целых чисел
2.1 Обзор типов целых чисел
В языке Go есть несколько встроенных типов целых чисел, классифицируемых следующим образом:
- Знаковые целые числа:
int8
,int16
,int32
(илиrune
),int64
иint
- Беззнаковые целые числа:
uint8
(илиbyte
),uint16
,uint32
,uint64
иuint
Размеры int
и uint
составляют 4 байта в 32-битных системах и 8 байт в 64-битных системах. Диапазоны значений типов данных целых чисел показаны в таблице ниже:
Тип | Диапазон значений |
---|---|
int8 | -128 до 127 |
uint8 | 0 до 255 |
int16 | -32768 до 32767 |
uint16 | 0 до 65535 |
int32 | -2147483648 до 2147483647 |
uint32 | 0 до 4294967295 |
int64 | -9223372036854775808 до 9223372036854775807 |
uint64 | 0 до 18446744073709551615 |
2.2 Использование целочисленных переменных
Базовый синтаксис объявления целочисленной переменной выглядит следующим образом:
var название_переменной тип_данных = начальное_значение
Пример кода:
package main
import "fmt"
func main() {
var a int = 10 // Переменная знакового целого числа
var b uint = 20 // Переменная беззнакового целого числа
var c int8 = -128 // Наименьшее значение типа int8
fmt.Println(a, b, c)
}
2.3 Операции с целыми числами
Язык Go поддерживает обычные арифметические операторы, такие как сложение (+
), вычитание (-
), умножение (*
), деление (/
) и взятие остатка (%
), а также побитовые операторы, такие как побитовое И (&
), ИЛИ (|
), исключающее ИЛИ (^
), побитовый сдвиг влево (<<
) и побитовый сдвиг вправо (>>
).
package main
import "fmt"
func main() {
x := 10
y := 3
// Арифметические операции
fmt.Println(x + y) // Сложение
fmt.Println(x - y) // Вычитание
fmt.Println(x * y) // Умножение
fmt.Println(x / y) // Деление
fmt.Println(x % y) // Остаток от деления
// Побитовые операции
fmt.Println(x & y) // Побитовое И
fmt.Println(x | y) // Побитовое ИЛИ
fmt.Println(x ^ y) // Исключающее ИЛИ
fmt.Println(x << 1) // Битовый сдвиг влево на 1
fmt.Println(x >> 1) // Битовый сдвиг вправо на 1
}
3 Типы данных с плавающей запятой
3.1 Обзор типов данных с плавающей запятой
В языке Go типы данных с плавающей запятой включают float32
и float64
, соответствующие 32-битным и 64-битным числам с плавающей запятой. В целом рекомендуется использовать float64
, поскольку он обеспечивает более широкий диапазон и более точную точность.
-
float32
имеет приблизительно 23 значащих бита, обеспечивая около 7 десятичных цифр точности. -
float64
имеет приблизительно 52 значащих бита, обеспечивая около 16 десятичных цифр точности.
3.2 Использование переменных с плавающей запятой
Переменные с плавающей запятой можно объявить, прямо указывая литералы, или использовать ключевое слово var
:
package main
import "fmt"
func main() {
var f1 float32 = 3.14 // Явно указываем тип float32
f2 := 3.14 // Автоматически выводится как тип float64
fmt.Println(f1, f2)
}
3.3 Арифметика с плавающей запятой и проблемы
Арифметика с плавающей запятой может привести к потере точности. Выполнение операций с очень высокой точностью является распространенной проблемой, особенно при вычитании двух очень близких чисел.
package main
import "fmt"
func main() {
f1 := .1
f2 := .2
f3 := f1 + f2
fmt.Println(f3) // Вывод может быть неожиданным .3 из-за потери точности
// Исправление потери точности с помощью форматированного вывода
fmt.Printf("%.1f\n", f3) // Вывод скорректирован до .3
}
4 Тип данных Boolean
4.1 Обзор типа Boolean
Boolean - самый простой тип данных, который может принимать только два значения: true
(истина) и false
(ложь). Он занимает очень важное положение в условных операторах и циклах.
4.2 Использование переменных типа Boolean
Объявление и использование булевых переменных:
package main
import "fmt"
func main() {
var success bool = true
var fail bool = false
fmt.Println("Операция выполнена успешно:", success)
fmt.Println("Операция завершилась неудачей:", fail)
}
Значения типа Boolean часто используются в условных операторах:
package main
import "fmt"
func main() {
a := 10
b := 20
fmt.Println("a == b:", a == b) // false
fmt.Println("a < b:", a < b) // true
}
5 Тип данных String
5.1 Обзор строк
Строка - это набор символов. В языке Go строки являются неизменяемыми. Каждая строка состоит из двух частей: указателя на базовый массив байтов и длины. Строки могут содержать любые данные, включая байты.
5.2 Использование строковых переменных
Обычно строковые переменные объявляются с использованием двойных кавычек "
для создания, но также можно использовать обратные кавычки ` для создания строк с несколькими строками:
package main
import "fmt"
func main() {
var s1 string = "привет"
s2 := "мир"
s3 := `Это
строка с
несколькими строками`
fmt.Println(s1)
fmt.Println(s2)
fmt.Println(s3)
}
После создания строки её содержимое изменить нельзя. Следующая операция недопустима и приведет к ошибке компиляции:
s := "привет"
s[] = 'П` // Ошибка компиляции: содержимое строки неизменно
5.3 Операции со строками
Строки являются очень распространенными и важными в программировании. В языке Go предоставляется богатый набор встроенных функций для манипуляции строками. Вот некоторые часто используемые операции.
5.3.1 Конкатенация строк
В языке Go можно использовать оператор плюс (+
) для конкатенации строк, что является самым простым способом. Кроме того, при работе с частой конкатенацией нескольких строк рекомендуется использовать strings.Builder
для более эффективной производительности.
package main
import (
"fmt"
"strings"
)
func main() {
// Конкатенация строк с использованием +
hello := "Привет, "
world := "Мир!"
result := hello + world
fmt.Println(result) // Вывод: Привет, Мир!
// Конкатенация строк с использованием strings.Builder
var sb strings.Builder
sb.WriteString("Привет, ")
sb.WriteString("Мир!")
fmt.Println(sb.String()) // Вывод: Привет, Мир!
}
5.3.2 Разделение строки
Разделение строк можно выполнить с помощью функции strings.Split
, которая разбивает строку на сегменты на основе указанного разделителя.
package main
import (
"fmt"
"strings"
)
func main() {
// Определение строки
sentence := "Go - это язык программирования с открытым исходным кодом"
// Разбиваем строку по пробелу
words := strings.Split(sentence, " ")
for _, word := range words {
fmt.Printf("%s\n", word)
}
// Вывод:
// Go
// это
// язык
// программирования
// с
// открытым
// исходным
// кодом
}
5.3.3 Доступ к индексу
В Go строка является неизменяемой последовательностью байтов. Вы можете использовать индексацию для доступа к определенным байтам в строке. Однако важно заметить, что так как строка может содержать многобайтовые символы (например, символы, закодированные в UTF-8), прямая индексация может не дать ожидаемого результата для одного символа.
package main
import "fmt"
func main() {
s := "Привет, мир"
for i := 0; i < len(s); i++ {
fmt.Printf("%d: %x\n", i, s[i])
}
// Примечание: это выведет шестнадцатеричное представление байтов, а не символов
}
Для перебора строки по символам, вы можете использовать цикл range
.
package main
import "fmt"
func main() {
s := "Привет, мир"
for index, runeValue := range s {
fmt.Printf("%d: %U '%c'\n", index, runeValue, runeValue)
}
// Вывод: индекс, кодировка Unicode и сам символ для каждого символа
}
5.3.4 Получение длины
Функция len
может получить длину строки, то есть длину базовой последовательности байтов. Для UTF-8 строк, если вам нужно получить количество символов (символов Unicode), вы должны использовать функцию utf8.RuneCountInString
. Она правильно обрабатывает многобайтовые символы.
package main
import (
"fmt"
"unicode/utf8"
)
func main() {
s := "Привет, мир"
fmt.Println("Длина байтов:", len(s)) // Вывод длины в байтах
fmt.Println("Длина символов:", utf8.RuneCountInString(s)) // Вывод длины символов
}
Из приведенного выше примера видно, что язык Go обеспечивает богатый набор библиотечных функций для операций со строками, что упрощает выполнение различных задач по обработке строк. При написании кода важно обратить внимание на различие между байтами и символами, особенно при работе с наборами символов, не входящих в ASCII.