🦋 Go 是静态类型的编程语言,这意味着每个变量都有一种类型。从大的方面来说 Go 有两种类型,即基本类型和组合类型。数据类型指定有效的 Go 变量可以保持的数据类型。
按基本数据类型分类
基本类型
布尔型
bool
的零值为 false
。
仅赋值为 true
和 false
来表示真假。Go 没有定义布尔类型的字面量形式,可以将 true
和 false
这两个预声明的有名常量当作布尔类型的字面量形式。
1 | package main |
数值类型
numeric
的零值为 0
(但是不同类型的零值在内存中占用的空间可能不同)。
整数型
包括有符号(Signed)和无符号(Unsigned)类型。
Type | Size | Range | Description |
---|---|---|---|
int8 | 1 | -128~127 or -2^7~2^7-1 | 有符号 8 位整形 |
uint8 | 1 | 0~255 or 2^8 | 无符号 8 位整形 |
int16 | 2 | -32768~32767 or -2^15~2^15-1 | 有符号 16 位整形 |
uint16 | 2 | 0~65535 or 2^16 | 无符号 16 位整形 |
int32 | 4 | -2147483648~2147483647 or -2^31~2^31-1 | 有符号 32 位整形 |
uint32 | 4 | 0~4294967295 or 2^31 | 无符号 32 位整形 |
int64 | 8 | -9223372036854775808~9223372036854775807 or -2^63~2^63-1 | 有符号 64 位整形 |
uint64 | 8 | 0~18446744073709551615 or 0~2^64 | 无符号 64 位整形 |
int | 4 or 8 | Platform dependent | 有符号 32 或 64 位整形 |
uint | 4 or 8 | Platform dependent | 无符号 32 或 64 位整形 |
uintptr | 4 or 8 | Platform dependent | 用于存放一个指针 |
uintptr
特性:
- 可以被转换为
unsafe.Pointer
,反之亦然; - 可以在其上执行算术运算;
- 即使包含指针地址,也只是一个值,也不引用任何对象。所以:
- 如果相应对象移动,则不会更新其值。例如:当 Goroutine 堆栈发生变化时;
- 相应的对象可以是被收集的垃圾;
uintptr
场景:
- 其上的是与
unsafe.Pointer
一起主要用于不安全的内存访问; - 当你想要保存指针地址值以进行打印或存储它。由于地址刚刚存储并且不引用任何内容,因此相应的对象可以是垃圾收集的;
1 | package main |
byte
为 uint8
的别名。因此它是一个整数值,此整数值为 8 位,它表示 0~255 之间的一个字节。单个字节可以代表 ASCII 字符。Go 没有任何 char
数据类型,因此字节用于表示 ASCII 字符。
1 | package main |
rune
为 int32
的别名。因此它是一个整数值,此整数值旨在表示 Unicode Code Point。关于 Unicode 和字符集请戳 The Absolute Minimum Every Software Developer Absolutely, Positively. Must Know About Unicode and Character Sets(No Excuses!)。
1 | package main |
整数类型有四种字面量形式:十进制形式(Decimal)、八进制形式(Octal)、十六进制形式(Hex)和二进制形式(Binary);
1 | // 十六进制表示 |
浮点型
在内存中,所有的浮点数都是使用 IEEE-754 格式存储的。
Type | Size | Range | Description |
---|---|---|---|
float32 | 4 | 正负1.18*10^-38~正负3.40*10^38 | 32 位的浮点型 |
float64 | 8 | 正负2.23*10^-308~正负1.80*10^308 | 64 位的浮点型 |
1 | package main |
浮点数类型值的字面量形式:一个浮点数的完整十进制字面量形式可能包含一个十进制整数部分、一个小数点、一个十进制小数部分和一个以 10 为底数的整数指数部分。整数指数部分字母 e
或 E
带一个十进制的整数字面量组成(xEn
表示 x
乘以 10^n
,而 xE-n
表示 x
除以 10^n
)。
1 | 10.1234 |
一些合法的浮点数的十六进制字面量:
1 | 0x1p-2 // == 1.0/4 = 0.25 |
复数型
Type | Size | Range | Description |
---|---|---|---|
complex64 | 8 | N/A | 64 位的复数型,由 float32 位的实部和虚部联合表示 |
complex128 | 16 | N/A | 128 位的复数型,由 float64 位的实部和虚部联合表示 |
1 | package main |
复数虚部字面量形式:一个虚部值的字面量形式由一个浮点数字面量或者一个整数字面量和其后跟随的一个小写的字母 i
组成。 在 Go 1.13 之前,如果虚部中 i
前的部分为一个整数字面量,则其必须为并且总是被视为十进制形式。
1 | 1.23i |
字符串型
string
的零值为 ""
,即空字符串。
1 | package main |
Go 字符串的字面量形式有两种:一种是解释型字面表示(Interpreted String Literal,双引号风格)。 另一种是直白字面表示(Raw String Literal,反引号风格)。
1 | // 解释形式 |
组合类型
非引用类型
数组
1 | package main |
结构体
1 | package main |
引用类型
切片
切片是动态大小的,数组是固定大小的,因此切片提供更灵活的接口。切片是引用类型,因为它在内部引用数组。它的内部表示通过三个字段:
- 底层数组的地址;
- 切片的长度;
- 切片的容量;
1 | package main |
映射
map
的零值是 nil
。
1 | package main |
通道
通道提供 Goroutine
之间的同步和通信。你可以将其视为管道,Goroutine
可以发送值和接收值。操作 <-
用于发送或接收,并指定数据流动方向的箭头方向。
两种类型的通道:
- 无缓冲通道(Unbuffered Channel):它没有任何容纳能力和值:
- 除非有另一个
Goroutine
接收,否则发送在频道上是阻塞的; - 接收是阻塞的,直到另一个
Goroutine
在一边去发送;
- 除非有另一个
- 带缓冲通道(Buffered Channel):可以在此处指定缓冲区的大小:
- 如果缓冲区已满,则仅发送阻塞的缓冲通道;
- 接收唯一的阻塞是通道的缓冲区是空的;
1 | package main |
函数
1 | package main |
指针
1 | package main |
Interface
interface
的零值是 nil
。
1 | package main |
空接口的特殊情况:
1 | package main |
数值类型运算符
- 算术运算符:
+
、-
、*
、/
、%
- 比较运算符:
==
、!=
、>
、>=
、<=
、<
- 逻辑运算符:
&&
、||
、!
- 增减运算符:
++
、--
- 按位运算符:
&
、|
、^
、<<
、>>
、&^
- 赋值运算符:
+=
、-=
、*=
、/=
、%=
、<<=
、>>=
、&=
、|=
、^=
运算符优化级
Priority | Category | Operator | Associativity |
---|---|---|---|
1 | Postfix | () [] -> . ++ -- | Left to right |
2 | Unary | + - ! ~ ++ -- (type)* & sizeof | Right to left |
3 | Multiplicative | * / % | Left to right |
4 | Additive | + - | Left to right |
5 | Shift | << >> | Left to right |
6 | Relational | < <= >= > | Left to right |
7 | Equality | == != | Left to right |
8 | Bitwise AND | & | Left to right |
9 | Bitwise XOR | ^ | Left to right |
10 | Bitwise OR | ⎮ | Left to right |
11 | Logical AND | && | Left to right |
12 | Logical OR | ⎮⎮ | Left to right |
13 | Assignment | = += -= *= /= %= = >>= <<= &= ^= ⎮= | Right to right |
14 | Comma | , | Left to right |