2024-07-12
한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina
我们上一篇文章中介绍了if和for,这不得练习下,让我们一起来实践一下如何使用 continue
语句来计算100以内的偶数之和。在我们编写代码的过程中,continue
语句将会帮助我们跳过某些不需要的迭代,比如在这个例子中,我们会跳过所有的奇数。
- sum := 0
- for i := 1; i < 100; i++{
- if i & 1 == 0 {
- continue
- }
- sum += i
- }
-
- fmt.Println("the sum is",sum)
在编程中,我们经常需要处理一组相同类型的元素,这些元素集合在 Go 语言中有特定的数据结构来表示。今天,我将为大家详细介绍 Go 中的几种集合类型:数组(array)、切片(slice)和映射(map)。
首先,让我们从数组开始。数组是 Go 中最基础的数据结构,它是一组具有相同类型元素的固定长度的序列。数组一旦声明,其长度就不可改变。数组的声明和初始化非常简单,
声明数组时,你需要指定数组类型和数组长度。以下是数组的声明方式:
var arrayName [arrayLength]elementType
例如,声明一个长度为 5 的整型数组:
var numbers [5]int
你可以通过多种方式初始化数组:
var numbers = [5]int{1, 2, 3, 4, 5}
:=
简短声明:numbers := [5]int{1, 2, 3, 4, 5}
numbers := [...]int{1, 2, 3, 4, 5}
numbers := [5]int{0: 1, 4: 5}
你可以通过索引来访问数组中的元素,索引从 0 开始:
value := numbers[2] // 获取索引为 2 的元素
你可以使用 for
循环来遍历数组中的所有元素:
- for i, value := range numbers {
- fmt.Printf("Index: %d, Value: %dn", i, value)
- }
你可以使用内置的 len
函数来获取数组的长度:
length := len(numbers)
如果数组没有显式初始化,它的元素将被自动设置为其类型的零值。例如,整型数组的零值是 0:
var numbers [5]int // 所有元素都是 0
Go 语言也支持多维数组。以下是声明和初始化一个 2x3 的整型数组的示例:
- var matrix [2][3]int
- matrix = [2][3]int{{1, 2, 3}, {4, 5, 6}}
由于数组的长度是固定的,这在某些情况下可能不太灵活。如果需要一个可变长度的集合,可以使用切片(slice)。
接下来是切片,它是一种更为灵活的内置类型,可以看作是动态数组。切片的长度是可变的,它基于数组创建,提供了更多的便利性。下面是如何声明和初始化一个切片:
- s := make([]int, 3) // 创建一个长度为3的整型切片
- s[0] = 1 // 切片元素赋值
- s[1] = 2
- s[2] = 3
- s = append(s, 4) // 向切片追加元素
在 Go 语言中,数组和切片虽然都用于存储一系列相同类型的元素,但它们在内存分配、大小可变性、以及使用方式上存在显著的不同。以下是数组和切片的主要区别:
[3]int
和 [4]int
是不同的类型。[]int
是所有整型切片的共同类型。make
函数或从数组中切片来初始化,不需要指定大小。以下是数组和切片的初始化示例:
- // 数组
- var arr [3]int = [3]int{1, 2, 3}
-
- // 切片
- var slice []int = []int{1, 2, 3}
- // 或者使用 make 函数
- slice := make([]int, 3)
append
函数添加元素,或者通过切片操作来获取子切片。切片的底层数组可能是在堆上分配的,访问切片元素的时间复杂度也是 O(1),但是 append
可能会导致底层数组的重新分配,这通常是 O(n) 操作。最后,我们来看看映射。映射是 Go 中的关联数组,它将键映射到值。映射的键可以是任何相等性操作符支持的类型,如整数、浮点数、字符串、指针、接口(只要接口内部包含的值是可比较的)、结构体和数组。映射的值可以是任何类型。
声明一个 map 的语法如下:
var mapName map[keyType]valueType
例如,声明一个键为字符串类型,值为整型类型的 map:
var scores map[string]int
在声明 map 之后,你需要通过 make
函数来初始化它,这样才能使用它:
scores = make(map[string]int)
或者,你可以使用简短声明并初始化:
scores := make(map[string]int)
也可以在声明的同时使用字面量进行初始化:
- scores := map[string]int{
- "alice": 90,
- "bob": 85,
- "charlie": 88,
- }
scores["alice"] = 90
value := scores["alice"]
如果键不存在,将返回该值类型的零值。
可以使用逗号-ok idiom 来检查键是否存在于 map 中:
- value, exists := scores["alice"]
- if exists {
- // 键存在
- } else {
- // 键不存在
- }
使用 delete
函数可以从 map 中删除一个键值对:
delete(scores, "alice")
如果键不存在,delete
函数什么也不做。
使用 for
循环可以遍历 map 中的所有键值对:
- for key, value := range scores {
- fmt.Printf("%s: %dn", key, value)
- }
map 的零值是 nil
。一个 nil
map 没有底层数据结构,并且不能添加元素。在向 map 添加元素之前,你必须使用 make
初始化它。
可以使用内置的 len
函数来获取 map 中键值对的数量:
length := len(scores)
map 的键可以是任何可以比较的类型,比如整数、浮点数、字符串、指针、接口(只要接口内部包含的值是可比较的)、结构体、数组等。切片、map 和函数不能用作 map 的键,因为这些类型不支持相等性比较。
在 Go 语言中,数组、切片和 map 是三种常用的数据结构,它们各自有不同的特点和注意事项。以下是一些在使用它们时需要注意的点:
nil
,在使用之前需要初始化。nil
,nil
map 不能用于存储键值对,使用前必须初始化。delete
删除不存在的键不会产生错误,但检查键是否存在是安全的做法。