阅读目录
数据类型概述
Go 支持的数据类型
基本数据类型
1 2 3 4 5 6 7 |
|
复合类型
1 2 3 4 5 6 7 |
|
一、变量、作用域、常量和枚举
变量声明和命名规则
纯粹的变量声明,Go 语言引入了关键字 var
,并且将类型信息放在变量名之后,此外,变量声明语句不需要使用分号作为结束符,比如我们要声明一个类型为 int 的变量 v1
,示例如下:
1 |
|
声明多个的变量
1 2 3 4 5 |
|
变量在声明之后,系统会自动将变量值初始化为对应类型的零值
注意事项:如果变量名包含多个单词,Go 语言变量命名规则遵循驼峰命名法,即首个单词小写,每个新单词的首字母大写,如 userName
,但如果你的全局变量希望能够被外部包所使用,则需要将首个单词的首字母也大写
变量初始化
声明变量时想要同时对变量值进行初始化,可以通过以下这些方式:
1 2 3 |
|
变量赋值与多重赋值
1 |
|
匿名变量
匿名变量通过下划线 _
来声明,任何赋予它的值都会被丢弃。
1 2 3 4 5 |
|
变量的作用域
1 |
|
二、常量
常量定义
通过 const
关键字定义常量时,可以指定常量类型,也可以省略(底层会自动推导),常见的常量定义方式如下:
1 2 3 4 5 6 7 8 |
|
预定义常量
Go 语言预定义了这些常量:true
、false
和 iota
前面两个熟悉其他语言的应该都很熟悉,是布尔类型的真假值,iota
比较特殊,可以被认为是一个可被编译器修改的常量,
在每一个 const
关键字出现时被重置为 0,然后在下一个 const
出现之前,每出现一次 iota
,其所代表的数字会自动增 1
从以下的例子可以基本理解 iota
的用法:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
|
如果两个 const
的赋值语句的表达式是一样的,那么还可以省略后一个赋值表达式。因此,上面的前两个 const
语句可简写为:
1 2 3 4 5 6 7 8 9 10 11 |
|
枚举
枚举中包含了一系列相关的常量,比如下面关于一个星期中每天的定义。Go 语言并不支持其他语言用于表示枚举的 enum
关键字,而是通过在 const
后跟一对圆括号定义一组常量的方式来实现枚举。
下面是一个常规的 Go 语言枚举表示法,其中定义了一系列整型常量:
1 2 3 4 5 6 7 8 9 10 |
|
常量的作用域
和函数体外声明的变量一样,以大写字母开头的常量在包外可见,函数体内声明的常量只能在函数体内生效。
三、布尔类型
Go 语言中的布尔类型与其他主流编程语言差不多,类型关键字为 bool
,可赋值且只可以赋值为预定义常量 true
和 false
。示例代码如下:
1 2 3 |
|
通过表达式计算得到的布尔类型结果可以赋值给 Go 布尔类型变量:
1 2 3 |
|
由于强类型的缘故,Go 语言在进行布尔值真假判断时,对值的类型有严格限制,以下这些值在进行布尔值判断的时候(使用非严格的 ==
比较符)都会被认为是 false
1 2 3 4 5 6 7 |
|
Go 语言中不同类型的值不能使用 ==
或 !=
运算符进行比较
四、整型
Go 语言默认支持如下这些整型类型:
类型 | 长度(单位:字节) | 说明 | 值范围 | 默认值 |
int8 |
1 | 带符号8位整型 | -128~127 | 0 |
uint8 |
1 | 无符号8位整型,与 byte 类型等价 |
0~255 | 0 |
int16 |
2 | 带符号16位整型 | -32768~32767 | 0 |
uint16 |
2 | 无符号16位整型 | 0~65535 | 0 |
int32 |
4 | 带符号32位整型,与 rune 类型等价 |
-2147483648~2147483647 | 0 |
uint32 |
4 | 无符号32位整型 | 0~4294967295 | 0 |
int64 |
8 | 带符号64位整型 | -9223372036854775808~9223372036854775807 | 0 |
uint64 |
8 | 无符号64位整型 | 0~18446744073709551615 | 0 |
int |
32位或64位 | 与具体平台相关 | 与具体平台相关 | 0 |
uint |
32位或64位 | 与具体平台相关 | 与具体平台相关 | 0 |
uintptr |
与对应指针相同 | 无符号整型,足以存储指针值的未解释位 | 32位平台下为4字节,64位平台下为8字节 | 0 |
五、运算符
算术运算符
Go 语言支持所有常规的整数四则运算:+
、-
、*
、/
和 %
(取余运算只能用于整数)
运算符 | 描述 |
+ | 相加 |
- | 相减 |
* | 相乘 |
/ | 相除 |
% | 求余 |
由于强类型的关系,在 Go 语言中,不同类型的整型值不能直接进行算术运算,比如下面这样计算就会报编译错误:
1 |
|
类型转化之后就好了:
1 |
|
在 Go 语言中,也支持自增/自减运算符,即 ++
/--
,但是只能作为语句,不能作为表达式,且只能用作后缀,不能放到变量前面
1 2 3 |
|
还支持 +=
、-=
、*=
、/=
、%=
这种快捷写法:
1 2 3 4 5 |
|
比较运算符
Go 语言支持以下几种常见的比较运算符: >
、<
、==
、>=
、<=
和 !=
运算符 | 描述 |
== | 检查两个值是否相等,如果相等返回 True 否则返回 False。 |
!= | 检查两个值是否不相等,如果不相等返回 True 否则返回 False。 |
> | 检查左边值是否大于右边值,如果是返回 True 否则返回 False。 |
>= | 检查左边值是否大于等于右边值,如果是返回 True 否则返回 False。 |
< | 检查左边值是否小于右边值,如果是返回 True 否则返回 False。 |
<= | 检查左边值是否小于等于右边值,如果是返回 True 否则返回 False。 |
比较运算符运行的结果是布尔值 ,不同类型的值不能放在一起比较,否则会报编译出错,如下:
1 2 3 |
|
相同类型的值才可以:
1 2 3 |
|
位运算符
位运算符对整数在内存中的二进制位进行操作,Go 语言支持以下这几种位运算符:
运算符 | 描述 |
& | 参与运算的两数各对应的二进位相与。 (两位均为1才为1) |
| | 参与运算的两数各对应的二进位相或。 (两位有一个为1就为1) |
^ | 参与运算的两数各对应的二进位相异或,当两对应的二进位相异时,结果为1。 (两位不一样则为1) |
<< | 左移n位就是乘以2的n次方。 “a<<b”是把a的各二进位全部左移b位,高位丢弃,低位补0。 |
>> | 右移n位就是除以2的n次方。 “a>>b”是把a的各二进位全部右移b位。 |
一些简单的测试
1 2 3 4 5 6 7 |
|
赋值运算符
运算符 | 描述 |
= | 简单的赋值运算符,将一个表达式的值赋给一个左值 |
+= | 相加后再赋值 |
-= | 相减后再赋值 |
*= | 相乘后再赋值 |
/= | 相除后再赋值 |
%= | 求余后再赋值 |
<<= | 左移后赋值 |
>>= | 右移后赋值 |
&= | 按位与后赋值 |
|= | 按位或后赋值 |
^= | 按位异或后赋值 |
逻辑运算符
运算符 | 含义 | 描述 |
x && y |
逻辑与运算符(AND) | 如果 x 和 y 都是 true,则结果为 true,否则结果为 false |
x || y |
逻辑或运算符(OR) | 如果 x 或 y 是 true,则结果为 true,否则结果为 false |
!x |
逻辑非运算符(NOT) | 如果 x 为 true,则结果为 false,否则结果为 true |
逻辑运算符计算的结果也是布尔值,通常我们可以组合使用逻辑运算符和比较运算符:
1 2 3 |
|
运算符优先级
上面介绍的 Go 语言运算符优先级如下所示(由上到下表示优先级从高到低,或者数字越大,优先级越高):
1 2 3 4 5 6 7 8 |
|
六、浮点型与复数类型
Go语言支持两种浮点型数:float32
和float64
。这两种浮点型数据格式遵循IEEE 754
标准: float32
的浮点数的最大范围约为 3.4e38
,可以使用常量定义:math.MaxFloat32
。 float64
的浮点数的最大范围约为 1.8e308
,可以使用一个常量定义:math.MaxFloat64
。
打印浮点数时,可以使用fmt
包配合动词%f
,代码如下:
1 2 3 4 5 6 7 8 9 |
|
定义一个浮点型变量的代码如下:
1 2 3 4 5 |
|
在实际开发中,应该尽可能地使用 float64
类型,因为 math 包中所有有关数学运算的函数都会要求接收这个类型。
浮点数的精度
浮点数不是一种精确的表达方式,因为二进制无法精确表示所有十进制小数,比如 0.1
、0.7
这种,下面我们通过一个示例来给大家直观演示下:
1 2 3 |
|
浮点数的比较
浮点数支持通过算术运算符进行四则运算,也支持通过比较运算符进行比较,但是涉及到相等的比较除外,看起来相等的两个十进制浮点数,在底层转化为二进制时会丢失精度,
如果一定要判断相等,下面是一种替代的解决方案:
1 2 3 4 5 |
|
七、字符串及底层字符类型
字符串
在 Go 语言中,字符串是一种基本类型,默认是通过 UTF-8 编码的字符序列,当字符为 ASCII 码时则占用 1 个字节,其它字符根据需要占用 2-4 个字节,比如中文编码通常需要 3 个字节。
声明和初始化
1 2 3 |
|
字符串转义符
转义符 | 含义 |
\r |
回车符(返回行首) |
\n |
换行符(直接跳到下一行的同列位置) |
\t |
制表符 |
\' |
单引号 |
\" |
双引号 |
\\ |
反斜杠 |
多行字符串
Go语言中要定义一个多行字符串时,就必须使用反引号
字符:
1 2 3 4 5 |
|
字符串的常用操作
方法 | 介绍 |
len(str) | 求长度 |
+或fmt.Sprintf | 拼接字符串 |
strings.Split | 分割 |
strings.contains | 判断是否包含 |
strings.HasPrefix,strings.HasSuffix | 前缀/后缀判断 |
strings.Index(),strings.LastIndex() | 子串出现的位置 |
strings.Join(a[]string, sep string) | join操作 |
字符串连接
字符串连接只需要通过 +
连接符即可
1 2 |
|
如果字符串长度较长,需要换行,则 +
连接符必须出现在上一行的末尾
1 2 |
|
字符串切片
1 2 3 4 5 6 7 |
|
它是一个左闭右开的区间,比如上述 str[0:5]
对应到字符串元素的区间是 [0,5)
,str[:5]
对应的区间是 [0,5)
(数组索引从 0 开始),str[7:]
对应的区间是 [7:len(str)]
(这是闭区间,是个例外,因为没有指定区间结尾)。
字符串遍历
字节数组的方式遍历:
1 2 3 4 5 6 |
|
Unicode 字符遍历:
1 2 3 4 |
|
将 Unicode 编码转化为可打印字符
1 2 3 4 |
|
八、基本数据类型之间的转化
数值类型之间的转化
整型之间的转化
进行类型转化时只需要调用要转化的数据类型对应的函数即可:
1 2 3 |
|
数值和布尔类型之间的转化
目前 Go 语言不支持将数值类型转化为布尔型,你需要自己根据需求去实现类似的转化。
字符串和其他基本类型之间的转化
将整型转化为字符串
整型数据可以通过 Unicode 字符集转化为对应的 UTF-8 编码的字符串:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
byte
是 uint8
的别名,rune
是 int32
的别名,所以也可以看做是整型数组和字符串之间的转化
strconv 包
Go 语言默认不支持将字符串类型强制转化为数值类型,即使字符串中包含数字也不行。
如果要实现更强大的基本数据类型与字符串之间的转化,可以使用 Go 官方 strconv
包提供的函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
|
参考链接:https://pkg.go.dev/strconv