mirror of
https://github.com/gopl-zh/gopl-zh.github.com.git
synced 2025-08-11 17:31:44 +00:00
回到简体
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
### 4.2.2. Slice內存技巧
|
||||
### 4.2.2. Slice内存技巧
|
||||
|
||||
讓我們看看更多的例子,比如镟轉slice、反轉slice或在slice原有內存空間脩改元素。給定一個字符串列表,下面的nonempty函數將在原有slice內存空間之上返迴不包含空字符串的列表:
|
||||
让我们看看更多的例子,比如旋转slice、反转slice或在slice原有内存空间修改元素。给定一个字符串列表,下面的nonempty函数将在原有slice内存空间之上返回不包含空字符串的列表:
|
||||
|
||||
<u><i>gopl.io/ch4/nonempty</i></u>
|
||||
```Go
|
||||
@@ -23,7 +23,7 @@ func nonempty(strings []string) []string {
|
||||
}
|
||||
```
|
||||
|
||||
比較微妙的地方是,輸入的slice和輸出的slice共享一個底層數組。這可以避免分配另一個數組,不過原來的數據將可能會被覆蓋,正如下面兩個打印語句看到的那樣:
|
||||
比较微妙的地方是,输入的slice和输出的slice共享一个底层数组。这可以避免分配另一个数组,不过原来的数据将可能会被覆盖,正如下面两个打印语句看到的那样:
|
||||
|
||||
```Go
|
||||
data := []string{"one", "", "three"}
|
||||
@@ -31,9 +31,9 @@ fmt.Printf("%q\n", nonempty(data)) // `["one" "three"]`
|
||||
fmt.Printf("%q\n", data) // `["one" "three" "three"]`
|
||||
```
|
||||
|
||||
因此我們通常會這樣使用nonempty函數:`data = nonempty(data)`。
|
||||
因此我们通常会这样使用nonempty函数:`data = nonempty(data)`。
|
||||
|
||||
nonempty函數也可以使用append函數實現:
|
||||
nonempty函数也可以使用append函数实现:
|
||||
|
||||
```Go
|
||||
func nonempty2(strings []string) []string {
|
||||
@@ -47,27 +47,27 @@ func nonempty2(strings []string) []string {
|
||||
}
|
||||
```
|
||||
|
||||
無論如何實現,以這種方式重用一個slice一般都要求最多爲每個輸入值産生一個輸出值,事實上很多這類算法都是用來過濾或合併序列中相鄰的元素。這種slice用法是比較複雜的技巧,雖然使用到了slice的一些技巧,但是對於某些場合是比較清晰和有效的。
|
||||
无论如何实现,以这种方式重用一个slice一般都要求最多为每个输入值产生一个输出值,事实上很多这类算法都是用来过滤或合并序列中相邻的元素。这种slice用法是比较复杂的技巧,虽然使用到了slice的一些技巧,但是对于某些场合是比较清晰和有效的。
|
||||
|
||||
一個slice可以用來模擬一個stack。最初給定的空slice對應一個空的stack,然後可以使用append函數將新的值壓入stack:
|
||||
一个slice可以用来模拟一个stack。最初给定的空slice对应一个空的stack,然后可以使用append函数将新的值压入stack:
|
||||
|
||||
```Go
|
||||
stack = append(stack, v) // push v
|
||||
```
|
||||
|
||||
stack的頂部位置對應slice的最後一個元素:
|
||||
stack的顶部位置对应slice的最后一个元素:
|
||||
|
||||
```Go
|
||||
top := stack[len(stack)-1] // top of stack
|
||||
```
|
||||
|
||||
通過收縮stack可以彈出棧頂的元素
|
||||
通过收缩stack可以弹出栈顶的元素
|
||||
|
||||
```Go
|
||||
stack = stack[:len(stack)-1] // pop
|
||||
```
|
||||
|
||||
要刪除slice中間的某個元素併保存原有的元素順序,可以通過內置的copy函數將後面的子slice向前依次移動一位完成:
|
||||
要删除slice中间的某个元素并保存原有的元素顺序,可以通过内置的copy函数将后面的子slice向前依次移动一位完成:
|
||||
|
||||
```Go
|
||||
func remove(slice []int, i int) []int {
|
||||
@@ -81,7 +81,7 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
如果刪除元素後不用保持原來順序的話,我們可以簡單的用最後一個元素覆蓋被刪除的元素:
|
||||
如果删除元素后不用保持原来顺序的话,我们可以简单的用最后一个元素覆盖被删除的元素:
|
||||
|
||||
```Go
|
||||
func remove(slice []int, i int) []int {
|
||||
@@ -95,12 +95,12 @@ func main() {
|
||||
}
|
||||
```
|
||||
|
||||
**練習 4.3:** 重寫reverse函數,使用數組指針代替slice。
|
||||
**练习 4.3:** 重写reverse函数,使用数组指针代替slice。
|
||||
|
||||
**練習 4.4:** 編寫一個rotate函數,通過一次循環完成镟轉。
|
||||
**练习 4.4:** 编写一个rotate函数,通过一次循环完成旋转。
|
||||
|
||||
**練習 4.5:** 寫一個函數在原地完成消除[]string中相鄰重複的字符串的操作。
|
||||
**练习 4.5:** 写一个函数在原地完成消除[]string中相邻重复的字符串的操作。
|
||||
|
||||
**練習 4.6:** 編寫一個函數,原地將一個UTF-8編碼的[]byte類型的slice中相鄰的空格(參考unicode.IsSpace)替換成一個空格返迴
|
||||
**练习 4.6:** 编写一个函数,原地将一个UTF-8编码的[]byte类型的slice中相邻的空格(参考unicode.IsSpace)替换成一个空格返回
|
||||
|
||||
**練習 4.7:** 脩改reverse函數用於原地反轉UTF-8編碼的[]byte。是否可以不用分配額外的內存?
|
||||
**练习 4.7:** 修改reverse函数用于原地反转UTF-8编码的[]byte。是否可以不用分配额外的内存?
|
||||
|
Reference in New Issue
Block a user