在PHP中,数组(array
)是一个万能的数据结构,既可以做索引数组,也可以做关联数组(哈希表)。Go则将这些功能拆分成了更专门、更高效的类型:数组、切片和Map。
3.1 数组 (Array) #
Go的数组是定长的,一旦定义了长度,就不能改变。这使得它在实际开发中不那么常用,但它是理解切片的基础。
func main() {
// 声明一个长度为3的整数数组,所有元素初始化为0
var a [3]int
fmt.Println(a) // [0 0 0]
// 声明并初始化
b := [3]int{10, 20, 30}
fmt.Println(b) // [10 20 30]
// 让编译器自动计算长度
c := [...]int{1, 2, 3, 4, 5}
fmt.Println(len(c)) // 5
// 数组是值类型,赋值或传参时会完整拷贝一份
d := b
d[0] = 99
fmt.Println(b) // [10 20 30] (b没有被改变)
fmt.Println(d) // [99 20 30]
}
3.2 切片 (Slice) #
切片是Go中最常用、最强大的集合类型,它动态可变,可以看作是PHP中索引数组的替代品。切片是对底层数组的一个“视图”或“引用”。
func main() {
// PHP: $arr = ['a', 'b', 'c'];
// Go:
s := []string{"a", "b", "c"}
// 使用make创建切片,指定长度和容量
// 创建一个长度为3,容量为5的切片
s2 := make([]string, 3, 5)
// 添加元素 (append会返回一个新的切片)
s = append(s, "d", "e")
fmt.Println(s) // [a b c d e]
fmt.Println("Length:", len(s)) // 长度: 5
fmt.Println("Capacity:", cap(s)) // 容量: (可能大于5,Go会自动扩容)
// 切片操作 (类似PHP的array_slice)
// s[low:high] -> 从索引low到high-1
sub := s[1:3] // 包含s[1]和s[2]
fmt.Println(sub) // [b c]
// 切片是引用类型
// 修改切片sub会影响到底层数组,从而影响原始切片s
sub[0] = "X"
fmt.Println(s) // [a X c d e] (s也被改变了)
}
3.3 Map #
Map是键值对的集合,等同于PHP中的关联数组。
func main() {
// PHP: $user = ['name' => 'John Doe', 'age' => 30];
// Go:
// 使用make创建map
user := make(map[string]interface{}) // `interface{}`是空接口,可以代表任何类型,类似PHP的混合类型
user["name"] = "John Doe"
user["age"] = 30
// 声明并初始化
scores := map[string]int{
"alice": 95,
"bob": 80,
}
fmt.Println(scores) // map[alice:95 bob:80]
// 读取值
fmt.Println(scores["alice"]) // 95
// 读取一个不存在的键,会返回该值类型的零值
fmt.Println(scores["charlie"]) // 0 (int的零值)
// 如何判断键是否存在?使用“comma ok”语法
score, ok := scores["charlie"]
if ok {
fmt.Println("Charlie's score:", score)
} else {
fmt.Println("Charlie is not in the map.")
}
// 删除键
delete(scores, "bob")
fmt.Println(scores) // map[alice:95]
}
3.4 结构体 (Struct) #
结构体是自定义的、将不同类型的字段聚合在一起形成的数据类型。它非常像PHP中的一个没有方法的class
,或者一个有固定键和类型的关联数组。
// 定义一个User结构体
type User struct {
ID int
FirstName string
LastName string
IsActive bool
}
func main() {
// 创建结构体实例
var u1 User
u1.ID = 1
u1.FirstName = "John"
u1.LastName = "Doe"
u1.IsActive = true
// 使用字面量创建
u2 := User{
ID: 2,
FirstName: "Jane",
LastName: "Doe",
IsActive: false,
}
// 也可以按顺序,但不推荐
u3 := User{3, "Alice", "Wonder", true}
fmt.Println(u1) // {1 John Doe true}
fmt.Println(u2.FirstName) // Jane
fmt.Println(u3)
}
Struct
是构建复杂数据模型的基础,在后续的Web开发和API设计中至关重要。