」工欲善其事,必先利其器。「—孔子《論語.錄靈公》
首頁 > 程式設計 > 切片:GO的骨幹!

切片:GO的骨幹!

發佈於2025-03-23
瀏覽:860

Slices: The Backbone of Go!好吧,让我们深入研究GO最通用和最重要的功能之一 - 切片。如果您来自另一种语言,您可能会认为切片类似于数组。而且,是的,它们确实有一些相似之处,但是切片为桌子带来了更多的力量,灵活性和特定的魔术! ?

无论如何是什么切片? ?

因此,GO中的切片实际上是基础数组上的“窗口”。您可以通过种植或收缩来更改此窗口的大小 - 它与切小菜单一样光滑。 ?

创建一个slice?

创建切片非常简单:


//使用文字 数字:= [] int {1,2,2,3,4,5} //使用制造功能 sliceofstrings:= make([] string,5)//一个5个字符串,每个串

初始化为一个空字符串
// Using a literal
numbers := []int{1, 2, 3, 4, 5}

// Using the make function
sliceOfStrings := make([]string, 5) // a slice of 5 strings, each 

长度和容量?

切片中的两个关键概念是长度和容量。长度是当前在切片中的元素数量,而容量是它可以调整大小之前可以保留的元素总数。

数字:= [] int {1,2,3} fmt.println(len(numbers))// 3 fmt.println(CAP(数字))// 3(在这里与长度相同)


开始附加物品时,只要填充容量就会增加一倍,因此您不必担心碰到天花板。

numbers := []int{1, 2, 3}
fmt.Println(len(numbers)) // 3
fmt.Println(cap(numbers)) // 3 (same as length here)
图案

附加切片:GO的内置魔术?✨
将元素添加到切片中就像GO的附加功能一样容易。您可以一次添加一个或多个元素,并且GO将为您处理所有调整大小和内存的内容。

numbers = append(numbers, 4)
fmt.Println(len(numbers)) // 4
fmt.Println(cap(numbers)) // probably 6 now, depending on Go’s growth 

此自动重构功能使切片非常方便,尤其是如果您不知道列表会得到多大。
切片切片?

numbers := []int{1, 2, 3}
numbers = append(numbers, 4, 5, 6) // Adding multiple elements at once
fmt.Println(numbers) // [1 2 3 4 5 6]
[1:4]中的

是包容性的,最后一个索引(4)是独有的。您最终以位于位置1、2和3的位置的元素,但不是4。

此子片仍然与原始切片共享相同的基础数组,因此更改将影响另一个片:

subslice [0] = 25 fmt.println(数字)// [10 25 30 40 50] fmt.println(subslice)// [25 30 40]

避免任何意外的更改,您可以使用复制来创建slice的独立版本:
numbers := []int{10, 20, 30, 40, 50}
subSlice := numbers[1:4] // Just takes a "slice" of the original slice
fmt.Println(subSlice) // [20 30 40]
[2 复制(新闻社,子列)

附加的容量变化?


如果您需要一个大于当前容量的切片,则附录将在后台自动创建一个新的,更大的数组并复制所有内容。这是令人难以置信的高效,并且是使切片令人敬畏的很大一部分。当附加创建一个新数组时,它将分配给先前的容量两倍 - 给您增长的空间!

切片和记忆效率?
subSlice[0] = 25
fmt.Println(numbers) // [10 25 30 40 50]
fmt.Println(subSlice) // [25 30 40]
这是一个小小的秘密:虽然切片超级强大,但如果您不小心,有时会导致内存泄漏。由于切片是指相同的基础数组,因此即使您只使用其中的一小部分,数组也可能保留在内存中。

例如:

newSlice := make([]int, len(subSlice))
copy(newSlice, subSlice)

在这种情况下,最好使用复制来创建一个真正独立的切片,该切片仅包含您需要的数据,释放其余内存。

[2 复制(minislice,smallslice)//现在完全分开!

多维切片?

需要一个以上的维度?您也可以创建多维切片!这对于网格或桌子之类的东西可能很方便。只需声明一片切片:

[2 {1,2,3}, {4,5,6}, {7,8,9}, } fmt.println(矩阵)// [[1 2 3] [4 5 6] [7 8 9]]


每个“行”本身就是一个切片,因此您可以在需要时独立种植它们。

[2 fmt.println(矩阵)// [[1 2 3 10] [4 5 6] [7 8 9]]
numbers := []int{1, 2, 3}
fmt.Println(len(numbers)) // 3
fmt.Println(cap(numbers)) // 3 (same as length here)
零切片?


nil slice只是尚未初始化的切片。它的长度和容量为零,但仍然可以与无恐慌之类的功能进行使用。

miniSlice := make([]int, len(smallSlice))
copy(miniSlice, smallSlice) // Now `miniSlice` is completely separate!

附加到零切片时,请自动为您初始化它。袖子是一个整洁的技巧。

陷阱和最佳实践?

注意共享内存:请记住,切片与原始数组共享内存。这非常适合性能,但是在切片大数组的一部分时要谨慎,以免将不需要的数据保存在内存中。
提防调整大小:当您附加时,如果当前容量已满,则可能需要创建一个新的基础数组。这比完成许多小型尺寸可能更有效,但是如果您要处理大型数据集,请注意开销。

避免过早优化:进行大量内存分配,并使用切片自动调整大小。通常,尝试对这些细节进行微观管理可能会使您的代码变得更加混乱,效率降低。在大多数情况下,信任GO的切片机制可以做正确的事情。
matrix := [][]int{
    {1, 2, 3},
    {4, 5, 6},
    {7, 8, 9},
}
fmt.Println(matrix) // [[1 2 3] [4 5 6] [7 8 9]]

版本聲明 本文轉載於:https://dev.to/learngo/slices-the-backbone-of-go-21ig?1如有侵犯,請聯繫[email protected]刪除
最新教學 更多>

免責聲明: 提供的所有資源部分來自互聯網,如果有侵犯您的版權或其他權益,請說明詳細緣由並提供版權或權益證明然後發到郵箱:[email protected] 我們會在第一時間內為您處理。

Copyright© 2022 湘ICP备2022001581号-3