Câu trả lời:
Ngoài câu trả lời của fabriziom , bạn có thể xem thêm các ví dụ khác tại " Go Slices: cách sử dụng và nội bộ ", trong đó đề cập đến việc sử dụng cho :[]int
Vì giá trị 0 của một lát cắt (
nil
) hoạt động giống như một lát cắt có độ dài bằng 0 , bạn có thể khai báo một biến lát cắt và sau đó thêm vào nó trong một vòng lặp:
// Filter returns a new slice holding only
// the elements of s that satisfy f()
func Filter(s []int, fn func(int) bool) []int {
var p []int // == nil
for _, v := range s {
if fn(v) {
p = append(p, v)
}
}
return p
}
Nó có nghĩa là, để thêm vào một lát, trước tiên bạn không phải cấp phát bộ nhớ: nil
lát cắt p int[]
đủ như một lát để thêm vào.
var p []int
dễ dàng hơn so với việc sử dụng make
(mà tôi liên kết nhiều hơn với cấp phát, mặc dù với giới hạn 0, nó sẽ không phân bổ bất cứ thứ gì). Về khả năng đọc, tôi không thích sử dụng make
ở đây.
p := []int{}
). Vì chúng ta thường sử dụng :=
cú pháp để khai báo hầu hết các biến, nên sẽ tự nhiên hơn nếu có nó ở mọi nơi thay vì có một ngoại lệ cho các slice. Khác với điều này, việc cố gắng nghĩ đến việc phân bổ thường thúc đẩy mọi người tiến tới tối ưu hóa quá sớm.
Khai báo đơn giản
var s []int
không phân bổ bộ nhớ và s
trỏ đến nil
, trong khi
s := make([]int, 0)
cấp phát bộ nhớ và s
trỏ tới bộ nhớ tới một lát cắt có 0 phần tử.
Thông thường, cái đầu tiên khó hiểu hơn nếu bạn không biết kích thước chính xác của trường hợp sử dụng của mình.
make
bản đồ, bởi vì ngay cả một khoảng trống cũng map
cần được phân bổ cho một số công việc ghi sổ.
nil
trong trường hợp lát cắt của bạn không có bất kỳ phần tử nào, thay vì một mảng trống. Tuy nhiên, nếu make
được sử dụng để tạo lát cắt, một mảng trống sẽ được trả về thay thế, đây thường là hiệu ứng mong muốn.
var s []int
) sẽ sản xuất null
, trong khi marshaling slice rỗng ( s := make([]int, 0)
) sẽ sản xuất dự kiến[]
Chỉ cần tìm thấy một sự khác biệt. Nếu bạn dùng
var list []MyObjects
và sau đó bạn mã hóa đầu ra dưới dạng JSON, bạn sẽ nhận được null
.
list := make([]MyObjects, 0)
kết quả []
như mong đợi.
make
Ví dụ hoàn toàn hơn một chút (thêm một đối số trong ):
slice := make([]int, 2, 5)
fmt.Printf("length: %d - capacity %d - content: %d", len(slice), cap(slice), slice)
Ngoài:
length: 2 - capacity 5 - content: [0 0]
Hoặc với loại động của slice
:
slice := make([]interface{}, 2, 5)
fmt.Printf("length: %d - capacity %d - content: %d", len(slice), cap(slice), slice)
Ngoài:
length: 2 - capacity 5 - content: [<nil> <nil>]
nil
lát, trong khi cái thứ hai tạo ra mộtempty
lát cắt (đây là thuật ngữ được sử dụng trong "Sách hành động" ). Để tránh đăng cùng một câu trả lời ở đây, bạn có thể kiểm tra stackoverflow.com/a/45997533/1561148