2-数据类型¶
整型¶
整型分为两大类:有符号
和无符号
按长度分为:int8
、int16
、int32
、int64
;uint8
、uint16
、uint32
、uint64
类型 | 范围 | 描述 | 对应C语言 |
---|---|---|---|
int8 | -128~127 | 有符号8位整型 | byte |
int16 | -32768~32767 | 有符号16位整型 | short |
int32 | -2147483648~2147483647 | 有符号32位整型 | int |
int64 | -9223372036854775808~9223372036854775807 | 有符号64位整型 | long |
uint8 | 0~255 | 无符号8位整型 | unsigned byte |
uint16 | 0·65535 | 无符号16位整型 | unsigned short |
uint32 | 0~4294967295 | 无符号32位整型 | unsigned int |
uint64 | 0~18446744073709551615 | 无符号64位整型 | unsigned long |
特殊整型¶
类型 | 描述 |
---|---|
uint | 32位OS上就是uint32,64位OS上就是uint64 |
int | 32位OS上就是int32,64位OS上就是int64 |
uintptr | 无符号整型,用于存放一个指针 |
注意
在使用 int
和 uint
类型时,不能假定它是32位或64位的整型,而要考虑int
和uint
可能在不同平台上的差异。
在涉及到 二进制传输、读写文件的结构描述 时,为了保持文件的结构不会受到不同编译目标平台字节长度的影响,不要使用int
和uint
。
数字字面量语法¶
字面量语法使得开发者可以用 二进制、八进制、十六进制的格式定义数字
v := 0b101110
,0b前缀;代表二进制的 101110,相当于八进制的56,十进制的46,十六进制的 2Ev := 0o56
,0o前缀;代表八进制的 56v := 46
,无前缀;代表十进制的 46v := 0x2e
,0x前缀;代表十六进制的 2Ev := 0x1p-2
,代表十六进制的 1 除以 \(2^2\),也就是 0.25
还可以用 _
来分隔数字。比如 v := 1_000_000
表示 v 的值等于 一百万 1000000。
借助 Printf()
可以将一个整数以不同进制形式展示
Tip
整型支持算术运算和位操作,算术表达式和位操作表达式的结果还是整型。 var a int = 1000 >> 2
浮点型¶
Go 语言支持两种浮点型数:float32
和float64
。
这两种浮点型数据格式遵循 IEEE754
标准:
float32
的浮点数最大范围约为3.4e38
,可以使用常量定义math.MaxFloat32
float64
的浮点数最大范围约为1.8e308
,可以使用常量定义math.MaxFloat64
打印浮点数时,可以使用占位符 %f
:
提示
- 浮点型字面量会被自动类型推断为 float64 类型
- 计算机很难进行浮点数的精确表示和存储,因此两个浮点数之间不应该使用
==
或!=
来比较,高精度科学计算应该使用 math 标准库
复数¶
complex64
和 complex128
Tip
Go 有三个内置函数处理复数:complex、real、imag
布尔值¶
Go 语言中以 bool
类型进行声明布尔型,布尔型数据只有 true
和 false
两个值。
- 布尔类型变量默认值为 false
- Go 语言中 不允许将整型强制转换为布尔型(integer !-> bool)
- 布尔型无法参与数值运算,无法与其他类型进行转换
字符串¶
Go 语言中的字符串是原生数据类型,使用字符串就像使用其他原生数据类型(int、bool、float32等)一样
Go 语言中字符串内部实现使用 UTF-8
编码,这使得 go 不需要专门使用 UTF-8 字符集的文本进行编码和解码,可以在Go语言中直接添加非ASCII码字符
字符串是一种值类型,且值不可变;即创建某个文本后你无法再次修改这个文本的内容,即使你改变了,你会发现那已经不是原来的那串字符串了。 更深入的讲,字符串是 字节的定长数组。
-
Go 支持以下2种形式的字面值
-
解释字符串
该类字符串使用双括号
""
引起来,其中转义字符(\n、\r、 \t、 \\
)会被替换。eg: -
非解释字符串
该类字符串使用反引号括起来 ``,支持换行。eg:
-
-
Go 中的字符串是根据长度限定,而非特殊字符
\0
。 - string 类型的零值:长度为 0 的字符串,即空字符串
""
- 可以通过
len()
函数来获取字符串字符个数 -
字符串中的内容(纯字节)可以通过标准索引法来获取
输出的是字符的 Ascii 码 -
字符串类型底层实现是一个二元的数据结构,一个是指向字节数组的起点,另一个是长度。 eg:
-
基于字符串创建的切片 和 原字符串 指向相同的 底层字符数组,一样不能修改,对字符串的切片操作返回的仍然是 string,而非 slice。
字符串常用操作¶
方法 | 描述 | 返回值 |
---|---|---|
len(str) | 求字符串长度 | int |
+ 或 fmt.Sprintf("%s %s", str1, str2) | 拼接字符串 | string |
strings.Split(str, 分隔符) | 分割字符串 | []string |
strings.Contains(str, 目标内容) | 判断str是否包含目标子串 | bool |
strings.HasPrefix(str, 目标内容) | 判断str是否以目标内容开头 | bool |
strings.HasSuffix(str, 目标内容) | 判断str是否以目标内容结尾 | bool |
strings.Index(str, 目标内容) | 返回str第一次出现目标内容的首个字符的下标 | int |
strings.LastIndex(str, 目标内容) | 返回str最后一次出现目标内容的首个字符的下标 | int |
strings.Join(strArr, 拼接符号) | 返回用拼接符号拼接strArr的字符串 | string |
字符¶
Go 的字符有以下两种:
- uint8类型,别名 byte,代表一个 ASCII 码字符
- int32类型,别名 rune,代表一个 UTF-8 字符
注意:字符用单引号( ' ' )括起来
当需要处理中文、日文或者中英混杂的字符时,则需要用到 rune 类型,因为 byte 型只有8位,只能显示 ASCII 码,而 rune 型有32位。
第二种方式 for...range
则可以正确的返回字符串中每个字符,因为它是按 rune 类型计算的,所以打印的时候没有乱码。
总结
- 字符串的底层是一个 byte 数组,所以字符串可以和
[]byte
型互相转换。 - 字符串是不能修改的
- 字符串是由 byte 字节组成的
- 字符串的长度是 byte 字节的长度
- rune 类型用来表示 utf8 字符
- 一个字符由一个或多个 byte 组成
修改字符串¶
- 将字符串转换成
[]byte
或[]rune
类型;例如[]byte(str)
或[]rune(str)
- 修改字符串
- 转回
string
注意
无论哪种转换,都会重新分配内存,并复制字节数组。
类型转换¶
Go语言中只有强制类型转换,没有隐式类型转换。该语法只能在两个类型之间支持相互转换的时候使用
基本语法如下:
详见类型转换
类型大小¶
Tip
使用 unsafe.Sizeof(v)
可以得到 v 占用内存大小。
类型 | bit数 |
---|---|
指针 | 32位 -> 4bit,64位C -> 8bit |
uintptr | 32位 -> 4bit,64位C -> 8bit |
bool | 8 |
byte | 8 |
int8 | 8 |
uint8 | 8 |
int16 | 16 |
uint16 | 16 |
int32 | 32 |
rune | 32 |
uint32 | 32 |
float32 | 32 |
int64 | 64 |
uint64 | 64 |
float64 | 64 |
complex64 | 64 |
complex128 | 128 |
int | 与CPU位数相同 |
uint | 与CPU位数相同 |
string | ASCII范围8bit,中文24bit |
类型别名、自定义类型¶
类型别名¶
为类型起个别名,方便代码编写过程中使用,
type
:关键字、alias
:类型别名、T
:类型
例如数据类型中提到的Unicode字符型 rune
和ASCII字符型 byte
就是类型别名
自定义类型¶
在 Go 中有一些基本的数据类型,如string
、int
、bool
等数据类型,也可以通过关键字 type
来定义自定义类型
自定义类型是定义了一个全新的类型,我们可以基于内置基本类型定义,也可以通过 struct 定义。 eg:
type
关键字的定义,Status
就是一种新的类型,它具有 bool
的特性
区别¶
从定义上看,类型别名有 =
,自定义类型没有。
Status
类型
ss 的类型是 string。abc
类型只会在代码中存在,编译前编译器会将其替换回来。