【高階資料型別】- 3. 切片的更多操作方法
我們已經知道,在進行“切片”操作的時候需要指定元素下界索引和元素上界索引,就像這樣:
numbers3[1:4]
在有些時候,我們還可以在方括號中放入第三個正整數,如下所示:
numbers3[1:4:4]
這第三個正整數被稱為容量上界索引。它的意義在於可以把作為結果的切片值的容量設定得更小。換句話說,它可以限制我們通過這個切片值對其底層陣列中的更多元素的訪問。下面舉個例子。讓我們先來回顧下在上一節講到的numbers3
和slice1
。針對它們的賦值語句是這樣的:
var numbers3 = [5]int{1, 2, 3, 4, 5} var slice1 = numbers3[1:4]
這時,變數slice1
的值是[]int{2, 3, 4}
。但是我們可以通過如下操作將其長度延展得與其容量相同:
slice1 = slice1[:cap(slice1)]
通過此操作,變數slice1
的值變為了[]int{2, 3, 4, 5}
,且其長度和容量均為4
。現在,numbers3
的值中的索引值在[1,5)範圍內的元素都被體現在了slice1
的值中。這是以numbers3
的值是slice1
的值的底層陣列為前提的。這意味著,我們可以輕而易舉地通過切片值訪問其底層陣列中對應索引值更大的更多元素。如果我們編寫的函式返回了這樣一個切片值,那麼得到它的程式很可能會通過這種技巧訪問到本不應該暴露給它的元素。這是確確實實是一個安全隱患。
如果我們在切片表示式中加入了第三個索引(即容量上界索引),如:
var slice1 = numbers3[1:4:4]
那麼在這之後,無論我們怎樣做都無法通過slice1
訪問到numbers3
的值中的第五個元素。因為這超出了我們剛剛設定的slice1
的容量。如果我們指定的元素上界索引或容量上界索引超出了被操作物件的容量,那麼就會引發一個執行時恐慌(程式異常的一種),而不會有求值結果返回。因此,這是一個有力的訪問控制手段。
雖然切片值在上述方面受到了其容量的限制,但是我們卻可以通過另外一種手段對其進行不受任何限制地擴充套件。這需要使用到內建函式append
。append
slice1 = append(slice1, 6, 7)
通過上述操作,slice1
的值變為了[]int{2, 3, 4, 6, 7}
。注意,一旦擴充套件操作超出了被操作的切片值的容量,那麼該切片的底層陣列就會被自動更換。這也使得通過設定容量上界索引來對其底層陣列進行訪問控制的方法更加嚴謹了。
我們要介紹的最後一種操作切片值的方法是“複製”。該操作的實施方法是呼叫copy
函式。該函式接受兩個型別相同的切片值作為引數,並會把第二個引數值中的元素複製到第一個引數值中的相應位置(索引值相同)上。這裡有兩點需要注意:
1. 這種複製遵循最小複製原則,即:被複制的元素的個數總是等於長度較短的那個引數值的長度。
2. 與append
函式不同,copy
函式會直接對其第一個引數值進行修改。
舉例如下:
var slice4 = []int{0, 0, 0, 0, 0, 0, 0} copy(slice4, slice1)
通過上述複製操作,slice4
會變為[]int{2, 3, 4,