Базовые типы данных
Сейчас мы их проверим, сейчас мы их сравним...
Врага нужно знать в лицо. Этим безотлагательно и займёмся.
В первую очередь нам следует запомнить, что Go является компилируемым языком со строгой типизацией. С этой позиции и будем двигаться дальше. Все счастливые семьи похожи друг на друга. Несмотря на то, что во всех языках база - это плюс-минус одинаково, в Go есть свои нюансы, которые надо знать.
В текущей реализации языка я насчитал 19 базовых типов данных, включая алиасы:
bool
string
int int8 int16 int32 int64 uint uint8 uint16 uint32 uint64 uintptr
byte // алиас для uint8
rune // алиас для int32, представляет номер данного Unicode символа (специфический для Go тип, зато тип char отсутствует)
float32 float64
complex64 complex128
BOOL
Булев тип предсказуемо занимает 1 байт. В Go этот тип переменных отличен тем, что, не привязан к числовым эквивалентам как, к примеру, в языке C, где таковые эквиваленты вовсе подменяют собой отсутствующий тип bool. То есть 0 автоматически не равен false, а значащее число - true. Более того, не поможет и явное приведение типов:
Однако логика предикатов ожидаемо работает, и математические выражения в булевом контексте могут трактоваться как значения бинарной true/false логики:
STRING
Строковый тип идёт со встроенной поддержкой юникода и только юникода (UTF-8). Байтовые последовательности прочих кодировок при оказии приходится всегда конвертировать с целью читаемости. Как к примеру в C#, строка в Go представляет собою неизменяемую последовательность байтов. То есть она как бы и массив (да и вообще строки и байтовые массивы - это как корпускулярно-волновой дуализм), однако строго необходимо помнить, что вольности, подобные таковым, не допускаются компилятором:
Как видите, компилятор не дал нам уподобиться Тилю Уленшпигелю и смешать "henep" и "senep" =)
К всякой строке может быть применена встроенная функция len, возвращающая длину подлежащего байтового массива, но никак не количество символов. Снова из-за строки выглядывают ослиные уши байтового массива, поскольку любой UTF-8 символ, не совпадающий с ASCII таблицей, потребует для своего выражения от 2 до 4 байтов. Достаточно взглянуть на богатство и разнообразие национальных языков и распространённых символов, которые вобрала в себя UTF.Кроме прочего, вы немало ошибётесь, если сведёте вопрос к символьно-байтовому дуализму. Ведь есть ещё таинственные руны! Так что, впереди нас ещё ожидает весьма увлекательное исследование строко-байто-рунного единения (трёхкваркового конфайнмента?) в трёх лицах и функций для освоения всего этого хозяйства. Это не сложно.
Как водится, строки подвержены конкатенации:
Поскольку параметром функции Println() пакета fmt является тип intarface (базовый для прочих, как object в C#), возможны конструкции с гетерогенными включениями:
Разумеется, в проект должны быть включены пакеты "fmt" и "time", объявлена функция main, что было опущено для краткости изложения.
Также существует понятие так называемого "raw string literal". По смыслу это соответствует строкам с символом @ в C# или тегу в HTML. Синтаксическим представляет собой косые кавычки ` `, те, что живут на букве "ё". Я часто использую такие литералы для интеграции в скомпилированный бинарник внешних ресурсов вроде картинок в формате base64.
Забегая вперёд, хочу продемонстрировать, какого рода в рамках "строко-байтового дуализма", возможны операции со строками:
Вот такая, с позволения сказать , конкатенация. Если размыслить, для меня это как у физиков - выражают же массы частиц в энергетическом эквиваленте. Масса T кварка 173,2 ± 0,7 ГэВ, и ничего, все радуются. Синхрофазотрон и полчаса работы лобзиком =)
Хотел удержаться, и обуздать размах мысли в целях соблюдения святой лапидарности, но всё же приведу таблицу HEX dictionary:
Hex to ASCII text conversion table
Hexadecimal
Binary
ASCII Character
00
00000000
NUL
01
00000001
SOH
02
00000010
STX
03
00000011
ETX
04
00000100
EOT
05
00000101
ENQ
06
00000110
ACK
07
00000111
BEL
08
00001000
BS
09
00001001
HT
0A
00001010
LF
0B
00001011
VT
0C
00001100
FF
0D
00001101
CR
0E
00001110
SO
0F
00001111
SI
10
00010000
DLE
11
00010001
DC1
12
00010010
DC2
13
00010011
DC3
14
00010100
DC4
15
00010101
NAK
16
00010110
SYN
17
00010111
ETB
18
00011000
CAN
19
00011001
EM
1A
00011010
SUB
1B
00011011
ESC
1C
00011100
FS
1D
00011101
GS
1E
00011110
RS
1F
00011111
US
20
00100000
Space
21
00100001
!
22
00100010
"
23
00100011
#
24
00100100
$
25
00100101
%
26
00100110
&
27
00100111
'
28
00101000
(
29
00101001
)
2A
00101010
*
2B
00101011
+
2C
00101100
,
2D
00101101
-
2E
00101110
.
2F
00101111
/
30
00110000
0
31
00110001
1
32
00110010
2
33
00110011
3
34
00110100
4
35
00110101
5
36
00110110
6
37
00110111
7
38
00111000
8
39
00111001
9
3A
00111010
:
3B
00111011
;
3C
00111100
<
3D
00111101
=
3E
00111110
>
3F
00111111
?
40
01000000
@
41
01000001
A
42
01000010
B
43
01000011
C
44
01000100
D
45
01000101
E
46
01000110
F
47
01000111
G
48
01001000
H
49
01001001
I
4A
01001010
J
4B
01001011
K
4C
01001100
L
4D
01001101
M
4E
01001110
N
4F
01001111
O
50
01010000
P
51
01010001
Q
52
01010010
R
53
01010011
S
54
01010100
T
55
01010101
U
56
01010110
V
57
01010111
W
58
01011000
X
59
01011001
Y
5A
01011010
Z
5B
01011011
[
5C
01011100
\
5D
01011101
]
5E
01011110
^
5F
01011111
_
60
01100000
`
61
01100001
a
62
01100010
b
63
01100011
c
64
01100100
d
65
01100101
e
66
01100110
f
67
01100111
g
68
01101000
h
69
01101001
i
6A
01101010
j
6B
01101011
k
6C
01101100
l
6D
01101101
m
6E
01101110
n
6F
01101111
o
70
01110000
p
71
01110001
q
72
01110010
r
73
01110011
s
74
01110100
t
75
01110101
u
76
01110110
v
77
01110111
w
78
01111000
x
79
01111001
y
7A
01111010
z
7B
01111011
{
7C
01111100
|
7D
01111101
}
7E
01111110
~
7F
01111111
DEL
Целочисленные типы
Первое, что о них нужно понимать, так это то, что они подвержены переполнению, что свойственно далеко не всем языкам (тому же, Pascal). Как и положено, существует "простой" архитектурно зависимый int . За ним следуют целые числа со знаком фиксированного размера — int8, int16, int32, int64 с аналогичным размером 8, 16, 32, 64 бита соответственно. Для исчисления диапазона значений данных типов необходимо воспользоваться формулой: −2n−1 до 2n−1−1, где n — размер типа.
Также, присутствуют и аналогичные беззнаковые типы - "обобщённый" uint, а также uint8, uint16, uint32, uint64. Число в названии типа, как и в предыдущем случае, задаёт размер, но диапазон значений составляет от 0 до 2n−1.
Рискуя заглянуть далеко вперёд, сообщу о том, что для преодоления ограничения домена значений переменных, к примеру uint64, а также осуществления операций с большими числами может использоваться специальный пакет "math/big", а также некоторые хитрости с нетипизированными константами, чья арифметика обрабатывается с гораздо большей числовой точностью, чем значения фундаментальных типов. Подробнее об этом мы поговорим позже.
Вещественные числа
Здесь всё предсказуемо. Числа с плавающей точкой представлены двумя типами - float32 и float64 - соответственно с простой и двойной точностью. Их размер составляет ожидаемые 32 и 64 бита в реализация соответствует стандарту IEEE 754. Размерность данных типов (так же как и, впрочем, всех целочисленных) можно увидеть, используя пакет "math":
math/big
Появление этого пакета в стандартной библиотеке Go привело к обсуждению такой сущности как числовые типы с неограниченной точностью. Позже я покажу на развёрнутом примере декодирования аппаратной информации (CID) вендора SD карт работу с пакетом math/big, большими числами, и даже битовыми оперциями с ними.
Комплексные числа
Физики любят говорить кОмпплексные, математики произносят комплЕксные числа.... Оставим это дело для математиков. Я же для красоты приведу вам такой код:
Скомпилировав и запустив его, зайдите в любом браузере на страницу http://localhost:3000 и получите эстетическое наслаждение. То самое, которое несёт математика в своей стройности. Ах да, я же совсем забыл рассказать о сборке программ и установке нужных для этого компонентов! Что ж, исправляюсь!
Last updated
Was this helpful?