Theo builtin api docs, append() sẽ phân bổ lại và sao chép vào một khối mảng mới khi dung lượng của slice gốc không đủ lớn.Khi nào Golang nối thêm() tạo một slice mới?
Đây là một (phiên bản đơn giản) của thuật toán đệ quy để tạo kết hợp bảng chữ cái (trong trường hợp này là booleans). Các thành viên của bảng chữ cái (đúng, sai) được đệ quy thêm vào một lát cho đến khi nó là độ dài chính xác, tại thời điểm nó được gửi qua kênh.
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)
}
}
Here là liên kết sân chơi với mã này. Ở đầu ra:
[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]
Dòng kết thúc bằng dấu chấm than là những dòng được gửi vào kênh từ AddOption. Những người không có những gì nổi lên ở phía bên kia (tức là trong chính()). Rõ ràng là các lát gửi qua kênh được thay đổi sau khi chúng được gửi đi.
Kể từ AddOption trả về ngay lập tức sau khi gửi slice, việc sửa đổi phải đến từ các khối mã
var newCombo []bool
for _, ch := range []bool{true, false} {
newCombo = append(combo, ch)
AddOption(c, newCombo, length-1)
}
Nhưng, theo các tài liệu, thêm() phải trả lại một lát mới (mũ (kết hợp) là không đủ lớn). Theo this answer, bộ mô tả lát được gửi tới AddOption phải là bản sao; điều đó có đúng không? Theo như tôi có thể nói, giá trị được gửi dưới dạng đối số thứ hai cho AddOption() hoặc là một con trỏ tới một bộ mô tả slice, hoặc append() không trả về một slice mới.
http://blog.golang.org/go-slices-usage-and-internals cũng như http://blog.golang.org/slices có thể liên quan đến câu hỏi của bạn. – dyoo
Xem thêm http://stackoverflow.com/questions/17332227/big-o-of-append-in-golang – nos