根据内置的 api docs,当原始切片的容量不够大时, append() 将重新分配并复制到新的数组块。
这是用于创建字母组合(在本例中为布尔值)的递归算法(的简化版本)。字母表的成员 (true, false) 被递归地添加到切片中,直到它的长度正确,然后通过通道发送。
package main
import (
"fmt"
)
func AddOption(c chan []bool, combo []bool, length int) {
if length == 0 {
fmt.Println(combo, "!")
c <- combo
return
}
var newCombo []bool
for _, ch := range []bool{true, false} {
newCombo = append(combo, ch)
AddOption(c, newCombo, length-1)
}
}
func main() {
c := make(chan []bool)
go func(c chan []bool) {
defer close(c)
AddOption(c, []bool{}, 4)
}(c)
for combination := range c {
fmt.Println(combination)
}
}
这是此代码的操场链接。在输出中:
[true true true true] !
[true true true false] !
[true true true false]
[true true true false]
[true true false true] !
[true true false false] !
[true true false false]
[true true false false]
[true false true true] !
[true false true false] !
[true false true false]
[true false true false]
[true false false true] !
[true false false false] !
[true false false false]
[true false false false]
[false true true true] !
[false true true false] !
[false true true false]
[false true true false]
[false true false true] !
[false true false false] !
[false true false false]
[false true false false]
[false false true true] !
[false false true false] !
[false false true false]
[false false true false]
[false false false true] !
[false false false false] !
[false false false false]
[false false false false]
以感叹号结尾的行是从 AddOption 发送到通道的行。那些没有出现在另一侧(即在 main() 中)。很明显,通过通道发送的切片在发送后发生了变化。
由于AddOption在发送切片后立即返回,因此修改必须来自代码块
var newCombo []bool
for _, ch := range []bool{true, false} {
newCombo = append(combo, ch)
AddOption(c, newCombo, length-1)
}
但是,根据文档, append() 应该返回一个新切片(cap(combo) 不够大)。根据这个答案,发送到 AddOption 的切片描述符应该是一个副本;这不是真的吗?据我所知,作为 AddOption() 的第二个参数发送的值要么是指向切片描述符的指针,要么 append() 不返回新切片。
倚天杖
素胚勾勒不出你
相关分类