1. 引言
Go 语言(又称 Golang)是一种静态类型、编译型的开源编程语言,由 Google 的 Robert Griesemer、Rob Pike 和 Ken Thompson 设计。其类型系统设计简洁而强大,旨在提高代码的可读性、安全性和执行效率。理解 Go 的数据类型是掌握这门语言的基础,本文将系统性地介绍 Go 语言中的所有数据类型,包括基本类型、复合类型以及类型声明与转换。
2. 基本数据类型
Go 语言的基本数据类型(也称为内置类型或原始类型)是构建更复杂数据结构的基石。
2.1 布尔类型 (bool)
布尔类型表示逻辑值,只有两个预定义的常量:true 和 false。
go
var isReady bool = true
var isDone = false // 类型推断
2.2 数值类型
2.2.1 整数类型
Go 提供了多种有符号和无符号整数类型,其大小在不同架构上保持一致。
| 类型 | 大小 | 范围 |
|---|---|---|
int8 |
8 位 | -128 到 127 |
int16 |
16 位 | -32768 到 32767 |
int32 |
32 位 | -2147483648 到 2147483647 |
int64 |
64 位 | -9223372036854775808 到 9223372036854775807 |
int |
平台相关(32或64位) | 与 int32 或 int64 相同 |
uint8 (byte) |
8 位 | 0 到 255 |
uint16 |
16 位 | 0 到 65535 |
uint32 |
32 位 | 0 到 4294967295 |
uint64 |
64 位 | 0 到 18446744073709551615 |
uint |
平台相关 | 与 uint32 或 uint64 相同 |
uintptr |
足够存放指针 | 用于底层编程 |
go
var age int = 30
var count uint64 = 10000000000
var b byte = 'A' // byte 是 uint8 的别名
2.2.2 浮点数类型
用于表示带小数点的数字。
float32: 单精度浮点数,提供约 6 位十进制精度。float64: 双精度浮点数,提供约 15 位十进制精度(默认类型)。
go
var pi float64 = 3.141592653589793
var temperature float32 = 36.5
2.2.3 复数类型
用于表示复数。
complex64: 实部和虚部都是float32。complex128: 实部和虚部都是float64(默认类型)。
go
var c1 complex64 = 1 + 2i
var c2 complex128 = complex(5, 7) // 5 + 7i
2.2.4 字符与符文类型 (rune)
rune: 是int32的别名,用于表示一个 Unicode 码点(一个字符)。
go
var ch rune = '中' // 存储的是 Unicode 码点 U+4E2D
2.3 字符串类型 (string)
字符串是不可变的字节序列,默认使用 UTF-8 编码。
go
var greeting string = "Hello, 世界"
var multiLine = `这是一个
多行
原始字符串字面量`
3. 复合数据类型
复合类型由基本类型或其他复合类型组合而成。
3.1 数组 (Array)
数组是具有固定长度且元素类型相同的数据结构。
go
var arr1 [3]int = [3]int{1, 2, 3}
arr2 := [5]string{"Go", "Java", "Python"} // 未指定元素默认为零值
arr3 := [...]int{10, 20, 30, 40} // 编译器推断长度为 4
3.2 切片 (Slice)
切片是对数组的连续片段的引用,是 Go 中最常用、最灵活的序列类型。它是动态的,拥有长度和容量。
go
// 从数组创建
arr := [5]int{1, 2, 3, 4, 5}
slice1 := arr[1:4] // [2, 3, 4]
// 使用 make 创建
slice2 := make([]int, 3, 5) // 长度3,容量5
// 直接声明并初始化
slice3 := []string{"apple", "banana"}
slice3 = append(slice3, "orange") // 动态追加元素
3.3 映射 (Map)
映射是键值对的无序集合,也称为字典或哈希表。
go
// 声明并初始化
scores := map[string]int{
"Alice": 95,
"Bob": 87,
}
// 使用 make 创建
ages := make(map[string]int)
ages["Charlie"] = 30
// 访问与判断存在
score, ok := scores["Alice"] // ok 为 true 表示键存在
3.4 结构体 (Struct)
结构体是字段的集合,用于定义自定义的复合数据类型。
go
type Person struct {
Name string
Age int
City string
}
// 初始化
p1 := Person{"小明", 25, "北京"}
p2 := Person{Name: "小红", City: "上海"} // Age 为零值 0
p3 := &Person{Name: "小刚"} // 创建指针
3.5 指针 (Pointer)
指针存储了另一个变量的内存地址。Go 支持指针,但不支持指针运算。
go
var x int = 42
var ptr *int = &x // ptr 指向 x
fmt.Println(*ptr) // 解引用,输出 42
*ptr = 100 // 通过指针修改 x 的值
3.6 函数类型 (Function Type)
在 Go 中,函数也是一种类型,可以作为参数传递或赋值给变量。
go
type Calculator func(int, int) int
var add Calculator = func(a, b int) int {
return a + b
}
result := add(5, 3) // 8
3.7 通道类型 (Channel)
通道是 Go 并发编程的核心,用于在 Goroutine 之间传递数据。
go
ch := make(chan int, 3) // 创建一个缓冲大小为 3 的整型通道
ch <- 1 // 发送数据到通道
value := <-ch // 从通道接收数据
3.8 接口类型 (Interface)
接口定义了一组方法签名,任何实现了这些方法的类型都隐式地满足了该接口。
go
type Speaker interface {
Speak() string
}
type Dog struct{}
func (d Dog) Speak() string { return "Woof!" }
var s Speaker = Dog{}
fmt.Println(s.Speak()) // 输出: Woof!
4. 类型声明与转换
4.1 类型别名与类型定义
- 类型定义 (
type NewType OldType): 创建一个全新的类型,与原有类型不兼容。 - 类型别名 (
type Alias = OldType): 只是原类型的一个别名,完全兼容。
go
type MyInt int // 类型定义,MyInt 和 int 是不同的类型
type YourInt = int // 类型别名,YourInt 就是 int
var a int = 5
var b MyInt = MyInt(a) // 需要显式转换
var c YourInt = a // 无需转换,因为 YourInt 就是 int
4.2 类型转换
Go 要求显式类型转换,不支持隐式转换。
go
var i int = 42
var f float64 = float64(i) // 将 int 转换为 float64
var u uint = uint(f) // 将 float64 转换为 uint
// 字符串与数值转换
str := "123"
num, _ := strconv.Atoi(str) // 字符串转整数
str2 := strconv.Itoa(456) // 整数转字符串
4.3 类型断言与类型开关
用于处理接口值的具体类型。
go
var i interface{} = "hello"
// 类型断言
s, ok := i.(string) // ok 为 true, s 为 "hello"
// n, ok := i.(int) // ok 为 false, n 为零值
// 类型开关
switch v := i.(type) {
case string:
fmt.Printf("It's a string: %s\n", v)
case int:
fmt.Printf("It's an int: %d\n", v)
default:
fmt.Printf("Unknown type: %T\n", v)
}
5. 零值 (Zero Value)
在 Go 中,声明但未显式初始化的变量会被赋予其类型的"零值"。
- 数值类型:
0 - 布尔类型:
false - 字符串:
""(空字符串) - 指针、切片、映射、通道、接口和函数:
nil
go
var num int // 0
var flag bool // false
var str string // ""
var slice []int // nil
var m map[string]int // nil
6. 总结
Go 语言的数据类型系统设计精炼而实用。从简单明确的基本类型,到功能强大的复合类型(尤其是切片、映射和结构体),再到支持并发和抽象的通道与接口,共同构成了 Go 高效、安全的编程基础。理解每种类型的特点、零值以及它们之间的转换规则,是编写健壮、高效 Go 程序的关键第一步。
建议初学者多动手实践,通过编写代码来加深对类型系统的理解。