TL;DR:本文介绍了在Golang中的基本数据类型
上一篇讲了变量,知道了怎么存数据。但存什么类型的数据,Go 有严格的规定
类型是什么
类型决定了两件事:这块内存能存什么样的数据,以及占多少空间
age := 20Go 看到 20,判断它是整数,分配一块能存整数的内存。如果你之后想往里存字符串,Go 直接报错,因为类型不匹配
这就是静态类型语言:每个变量的类型在编译阶段就确定了,不能在运行时随意改变
整数
Go 的整数类型分两类:有符号和无符号
有符号整数(可以存负数):
| 类型 | 占用空间 | 范围 |
|---|---|---|
| int8 | 1 字节 | -128 到 127 |
| int16 | 2 字节 | -32768 到 32767 |
| int32 | 4 字节 | -21 亿 到 21 亿 |
| int64 | 8 字节 | 极大 |
| int | 平台相关 | 32 位系统是 int32,64 位是 int64 |
无符号整数(只能存正数和零):
| 类型 | 占用空间 | 范围 |
|---|---|---|
| uint8 | 1 字节 | 0 到 255 |
| uint16 | 2 字节 | 0 到 65535 |
| uint32 | 4 字节 | 0 到 42 亿 |
| uint64 | 8 字节 | 极大 |
| uint | 平台相关 | 同 int |
绝大多数情况直接用 int,不用纠结有的没的。只有在特定场景才考虑具体的类型,比如处理文件字节用 uint8,和 C 语言交互用 int32,需要超大数字用 int64
age := 20 // int,自动推断var count int64 = 1000000000000 // 明确指定 int64整数溢出
每种类型有范围上限,超过了会溢出,不报错但结果是错的:
var n int8 = 127n = n + 1fmt.Println(n) // 输出 -128,溢出了int8 最大是 127,加 1 之后超出范围,绕回到 -128。Go 不会自动检测溢出,这是你自己要注意的
数字字面量的写法
除了十进制,Go 还支持其他进制和下划线分隔:
a := 100 // 十进制b := 0b1100100 // 二进制,前缀 0bc := 0o144 // 八进制,前缀 0od := 0x64 // 十六进制,前缀 0x
big := 1_000_000 // 下划线分隔,纯粹提高可读性,值还是 1000000浮点数
浮点数就是带小数点的数字。Go 有两种:
| 类型 | 占用空间 | 精度 |
|---|---|---|
| float32 | 4 字节 | 约 6-7 位有效数字 |
| float64 | 8 字节 | 约 15-16 位有效数字 |
日常用 float64,精度更高,也是 Go 默认推断的浮点类型:
height := 1.75 // 自动推断为 float64var pi float32 = 3.14159浮点数的精度问题
浮点数在计算机里是用二进制近似表示的,某些小数无法精确表示:
a := 0.1b := 0.2fmt.Println(a + b) // 输出 0.30000000000000004,不是 0.3这不是 Go 的 bug,是所有编程语言都有的浮点数问题。涉及金额计算时绝对不要用浮点数,应该用整数(比如存分而不是存元)
算钱用浮点,迟早被人扁
科学计数法
a := 1e3 // 1000.0b := 1.5e-2 // 0.015布尔
布尔类型只有两个值:true 和 false,用于判断条件
isAdmin := trueisLoggedIn := false布尔值不能和整数互转,这点和 C 语言不一样:
var n int = 1var b bool = n // ❌ 报错,int 不能赋给 bool在 C 里 0 是 false、非 0 是 true,但 Go 不允许这样做,必须明确写 true 或 false
字符串
字符串是一串字符,用双引号括起来:
name := "Chongxi"greeting := "Hi, Go!"字符串是不可变的
一旦创建,字符串的内容不能修改:
name := "Chongxi"name[0] = 'L' // ❌ 报错,字符串不可修改要修改只能创建新字符串
字符串拼接
用 + 拼接:
firstName := "Chong"lastName := "xi"fullName := firstName + lastNamefmt.Println(fullName) // Chongxi大量拼接用 strings.Builder,比 + 效率高很多,后面标准库篇会详细讲
多行字符串
用反引号,原样保留所有内容包括换行和缩进:
text := `第一行第二行第三行`fmt.Println(text)反引号里的内容不处理转义字符,\n 就是两个字符 \ 和 n,不是换行
转义字符
双引号字符串里可以用转义字符:
fmt.Println("第一行\n 第二行") // \n 是换行fmt.Println("用\"引号\"括起来") // \" 是双引号本身fmt.Println("路径:C:\\Users") // \\ 是反斜杠字符串长度
len() 返回字节数,不是字符数:
name := "张三"fmt.Println(len(name)) // 输出 6,不是 2因为中文每个字符占 3 个字节(UTF-8 编码),“重熙”是 6 个字节。要得到字符数,后面字符串深入那篇会讲
byte 和 rune
这两个类型和字符串关系密切,先简单了解:
byte 是 uint8 的别名,表示一个字节,处理 ASCII 字符用:
var b byte = 'A'fmt.Println(b) // 输出 65,'A' 的 ASCII 码rune 是 int32 的别名,表示一个 Unicode 字符,处理中文等字符用:
var r rune = ' 张 'fmt.Println(r) // 输出 24352,' 张 ' 的 Unicode 码注意字符用单引号,字符串用双引号,两者不一样
字符串和 byte、rune 的深入关系放到下一篇单独讲,内容比较多
复数
Go 内置支持复数,科学计算会用到,日常开发基本不会遇到:
var c complex64 = 1 + 2ivar d complex128 = 3 + 4i知道有这个东西就行
类型推断的规则
使用 := 时,Go 按以下规则推断类型:
a := 42 // intb := 3.14 // float64c := true // boold := "hello" // stringe := 'A' // rune(int32)整数默认推断为 int,浮点数默认推断为 float64。如果你需要别的类型,必须显式声明:
var a int32 = 42var b float32 = 3.14类型转换
Go 不做隐式类型转换,不同类型之间必须显式转换:
var a int = 42var b float64 = float64(a) // int 转 float64var c int = int(b) // float64 转 int,小数部分直接丢弃float64 转 int 不会四舍五入,直接截断小数部分:
var f float64 = 3.99var n int = int(f)fmt.Println(n) // 输出 3,不是 4整数之间转换要注意范围,大类型转小类型可能溢出:
var a int32 = 1000var b int8 = int8(a)fmt.Println(b) // 输出 -24,溢出了字符串和数字互转不能直接用类型转换,要用 strconv 包,下一篇类型转换会专门讲
常量与类型
常量用 const 声明,值在编译阶段就确定,不能修改:
const Pi = 3.14159const AppName = "MyApp"常量可以没有明确类型,这叫无类型常量,它的类型在使用时才确定:
const x = 42 // 无类型整数常量
var a int = x // x 当作 int 用var b float64 = x // x 当作 float64 用这种灵活性让常量在赋值时不需要显式转换,比普通变量方便
下一篇单独讲字符串,byte 和 rune 的区别,中文字符怎么处理,以及 strings 包的常用操作
Auth_Verified: 2026.05.03