第12讲 Go基本数据类型
本讲基于视频实际讲解内容整理
一、Go与Java数据类型对比
1.1 Java的基本类型
老师首先回顾了Java的基础类型特点:
- Java中基础的
int类型是完全不能自定义的,int的尺寸永远不变 - Java是跨平台语言,原生基本类型的内存由 JVM统一规定,保证"一次编译,到处运行"
- C/C++则不同,不同平台下基本类型大小可能变化
- Java中有替代方案
byte来替代int以减少内存占用
1.2 Go的数据类型优势
Go语言提供了更灵活的数值类型选择,可以针对不同场景选择不同大小的类型,从而写出高性能的代码。
二、整数类型
2.1 有符号整数(int)
| 类型 | 大小 | 范围 |
|---|---|---|
| int8 | 1字节 | -128 ~ 127 |
| int16 | 2字节 | -32768 ~ 32767 |
| int32 | 4字节 | -2147483648 ~ 2147483647 |
| int64 | 8字节 | 更大范围 |
2.2 无符号整数(uint)
| 类型 | 大小 | 范围 |
|---|---|---|
| uint8 | 1字节 | 0 ~ 255 |
| uint16 | 2字节 | 0 ~ 65535 |
| uint32 | 4字节 | 0 ~ 4294967295 |
| uint64 | 8字节 | 更大范围 |
2.3 平台相关类型
int 和 uint 是与CPU平台相关的类型,不指定大小时:
- 在不同的操作系统中大小不一样
- 不同的编译器即使在相同硬件平台上也可能产生不同的大小
2.4 溢出演示
老师在视频中演示了类型溢出的效果:
Go
package main
import "fmt"
func main() {
// uint8 范围 0~255,超出会溢出
var u uint8 = 255
fmt.Println(u) // 255
// u = u + 1 // 溢出后会变成 0
// int8 范围 -128~127
var a int8 = 127
fmt.Println(a) // 127
// a = 128 // 编译报错:超出范围!
// int8 赋值 200 会报错
// var b int8 = 200 // constant 200 overflows int8
// 改用 uint16 就可以了
var c uint16 = 300
fmt.Println(c) // 300
// 各种整数类型
var d int32 = 100
var e int64 = 200
fmt.Println(d, e)
}
关键要点:使用数据类型时一定要注意范围限制,不要让它溢出。
三、浮点数类型
3.1 两种精度
| 类型 | 大小 | 精度 |
|---|---|---|
| float32 | 4字节 | 单精度 |
| float64 | 8字节 | 双精度 |
3.2 浮点数运算
Go
package main
import "fmt"
func main() {
// 浮点数声明
a := 20.0129999
fmt.Println(a)
// Go是强类型语言,不同类型不能直接混合运算
// var b int = 10
// var c float64 = 20.5
// result := b + c // 编译报错!类型不匹配
// 浮点数的格式化输出
// %g - 更紧凑的表示
// %e - 科学计数法
}
3.3 强类型语言的严格性
老师特别强调:
"Go是强类型的语言,不同的数字不能直接混合运算。"
- Go强制你写出健全的代码
- 不同类型之间不能直接运算,需要显式类型转换
- 未使用的变量也会直接报错(不仅仅是警告)
- 老师提到 Rust语言在这方面更加严格
四、复数类型
4.1 complex64 和 complex128
Go
package main
import "fmt"
func main() {
// 复数声明
var c complex64 = 10 + 0i
fmt.Println(c)
// 使用 i 表示虚部
var d = 0 + 10i
fmt.Println(d)
// 1 + 2i
var e = 1 + 2i
fmt.Println(e) // (1+2i)
}
4.2 复数的规则
- 一个浮点数字面量后面跟
i,它就是一个复数的虚部 - 复数的实部默认为0
- 常量算数规则下,复数可以加到另一个普通数值常量上
老师说明:复数类型目前用不上,先体验一下,后面用到再说。
五、布尔类型(bool)
Go
package main
import "fmt"
func main() {
// 布尔类型使用 true 和 false
var b bool = true
fmt.Println(b) // true
// 比较运算
a := 10
fmt.Println(a == 10) // true
fmt.Println(a > 5) // true
// 不同类型不能直接比较
// var c int = 10
// var d int8 = 16
// fmt.Println(c == d) // 编译报错!类型不匹配
// 相同类型可以比较
var e int = 10
var f int = 10
fmt.Println(e == f) // true
}
六、字符串类型(string)
6.1 基本概念
- 字符串是一个不可改变的字节序列
- 包括 byte(值的零)和 rune
- 通常用来包含人类可读的文本
- Go已经采用 UTF-8编码,可以直接使用中文
6.2 字符串操作
Go
package main
import "fmt"
func main() {
// 直接使用中文(UTF-8编码)
a := "我是中国人"
fmt.Println(a)
// 字符串长度(字节数)
fmt.Println(len(a))
// 通过下标访问字节
fmt.Println(a[0]) // 输出字节值
fmt.Println(a[1])
fmt.Println(a[2]) // 中文字符的第一个字节值是 97...
}
6.3 ASCII编码
老师讲解了字符串中数字的来源:
- ASCII 是一个标准编码
- 用 7位二进制 表示字符
- 所有英文字符都有对应的ASCII码值
- 例如:
'a'的ASCII码是 97
七、指针与数据类型的结合
老师在本讲中还结合指针做了演示:
Go
package main
import "fmt"
func main() {
a := 10
fmt.Println(&a) // 取内存地址
b := &a // b 存储a的地址
fmt.Println(b) // 输出地址
fmt.Println(*b == a) // true,说明b确实指向a
}
八、本讲小结
| 知识点 | 要点 |
|---|---|
| 整数类型 | int8/16/32/64(有符号)、uint8/16/32/64(无符号) |
| 平台相关 | int/uint 大小取决于CPU平台和编译器 |
| 溢出 | 超出类型范围会溢出或编译报错 |
| 浮点数 | float32(单精度)、float64(双精度) |
| 强类型 | 不同类型不能直接混合运算 |
| 复数 | complex64/complex128,用 i 表示虚部 |
| 布尔 | true/false,不同类型不能直接比较 |
| 字符串 | 不可变字节序列,UTF-8编码,可直接用中文 |
| ASCII | 7位二进制表示字符的标准编码 |
| 指针 | &取地址,*解引用 |
九、课后练习
- 声明
int8、uint8、int32、uint64类型的变量,分别赋值并打印 - 尝试给
int8赋值 200,观察编译报错信息 - 声明一个
float64变量,尝试与int类型变量直接相加,观察报错 - 声明一个包含中文的字符串,使用
len()和下标访问观察输出 - 使用
&和*操作符,验证指针指向的值与原变量是否相等