第 2 章:基本数据类型与变量
jerry北京市2026年4月24日Go 5 次阅读 约 10 分钟

掌握 Go 的类型系统、变量声明方式、常量定义以及零值机制。
2.1 变量声明
Go 有多种变量声明方式:
// 方式一:完整声明
var name string = "Go"
// 方式二:类型推断
var age = 25
// 方式三:短变量声明(只能在函数内使用,最常用)
city := "Beijing"
// 方式四:批量声明
var (
x int
y string
z bool
)
短变量声明 := 是日常开发中最常用的方式,但注意它只能在函数体内使用。
2.2 基本数据类型
整数类型
| 类型 | 大小 | 范围 |
|---|---|---|
int8 |
1 字节 | -128 ~ 127 |
int16 |
2 字节 | -32768 ~ 32767 |
int32 |
4 字节 | -2^31 ~ 2^31-1 |
int64 |
8 字节 | -2^63 ~ 2^63-1 |
int |
平台相关 | 32 位或 64 位 |
uint8 (byte) |
1 字节 | 0 ~ 255 |
uint16 |
2 字节 | 0 ~ 65535 |
uint32 |
4 字节 | 0 ~ 2^32-1 |
uint64 |
8 字节 | 0 ~ 2^64-1 |
var a int = 42
var b int64 = 9223372036854775807
var c byte = 'A' // byte 是 uint8 的别名
浮点数
var f1 float32 = 3.14
var f2 float64 = 3.141592653589793 // 默认推断为 float64
布尔类型
var ok bool = true
// Go 中布尔值不能与整数互转,不能用 0/1 代替
字符串
s1 := "Hello" // 双引号:解释型字符串
s2 := `Hello\nWorld` // 反引号:原始字符串,不转义
// 字符串是不可变的
// s1[0] = 'h' // 编译错误
// 字符串拼接
s3 := s1 + " World"
// 常用操作
len(s1) // 字节长度:5
fmt.Println([]rune("你好")) // 转为 rune 切片处理中文
rune 类型
// rune 是 int32 的别名,表示一个 Unicode 码点
var r rune = '中'
fmt.Println(r) // 输出:20013(Unicode 码点)
// 遍历中文字符串
for i, ch := range "你好Go" {
fmt.Printf("索引:%d 字符:%c\n", i, ch)
}
2.3 零值(Zero Value)
Go 中所有变量在声明时如果没有显式赋值,会被自动初始化为该类型的零值:
| 类型 | 零值 |
|---|---|
int, float64 等数值类型 |
0 |
bool |
false |
string |
"" (空字符串) |
| 指针、切片、映射、通道、函数、接口 | nil |
var i int // 0
var f float64 // 0
var b bool // false
var s string // ""
var p *int // nil
这是 Go 的一个重要设计:不存在"未初始化的变量"。
2.4 常量
const pi = 3.14159
const (
StatusOK = 200
StatusNotFound = 404
)
iota 枚举器
iota 是 Go 的常量计数器,在 const 块中从 0 开始自增:
const (
Sunday = iota // 0
Monday // 1
Tuesday // 2
Wednesday // 3
Thursday // 4
Friday // 5
Saturday // 6
)
// 常见技巧:位运算
const (
Read = 1 << iota // 1
Write // 2
Execute // 4
)
// 跳过某个值
const (
A = iota // 0
_ // 1(跳过)
C // 2
)
2.5 类型转换
Go 没有隐式类型转换,所有转换必须显式进行:
var i int = 42
var f float64 = float64(i) // int -> float64
var u uint = uint(f) // float64 -> uint
// 字符串与数字互转
import "strconv"
s := strconv.Itoa(42) // int -> string: "42"
n, err := strconv.Atoi("42") // string -> int: 42
// 字符串与字节切片互转
bs := []byte("hello") // string -> []byte
str := string(bs) // []byte -> string
2.6 类型别名与自定义类型
// 自定义类型(创建新类型)
type Celsius float64
type Fahrenheit float64
var temp Celsius = 36.5
// var f Fahrenheit = temp // 编译错误:类型不同
// 类型别名(只是别名,本质相同)
type MyInt = int
var x MyInt = 10
var y int = x // OK,因为 MyInt 就是 int
自定义类型和类型别名的区别是面试常考点:
- 自定义类型
type A B创建了一个全新的类型,不能直接赋值 - 类型别名
type A = B只是起了个别名,完全等价
2.7 面试要点
-
:=和var的区别是什么?:=只能在函数内使用,自动推断类型var可以在函数外使用,可以显式指定类型
-
Go 的零值机制有什么好处?
- 避免未初始化变量的 bug
- 简化代码,很多场景不需要显式初始化
-
byte和rune的区别?byte=uint8,表示一个 ASCII 字符或一个字节rune=int32,表示一个 Unicode 码点
-
为什么 Go 没有隐式类型转换?
- 避免隐式转换带来的精度丢失和意外行为
- 让代码意图更明确
练习
- 声明不同类型的变量,打印它们的零值
- 使用
iota定义一组表示文件权限的常量(读、写、执行) - 编写一个程序,将华氏温度转换为摄氏温度:
C = (F - 32) * 5 / 9 - 遍历字符串
"Hello, 世界"并打印每个字符及其索引
评论
登录 后发表评论
暂无评论