Một Go Slice chứa ba yếu tố: dữ liệu, độ dài và năng lực.
s := make([]int, 0, 10)
Biến s là một lát ints với chiều dài từ 0 và công suất 10 built-in len() và nắp() chức năng cho phép bạn để có được độ dài và năng lực của một lát:
len(s) == 0
cap(s) == 10
Để tăng chiều dài của một lát, chỉ cần tái lát:
s = s[0:5]
// len(s) == 5
// cap(s) == 10
Để giảm độ dài, bạn có thể mất một sub-lát:
s = s[0:1]
// len(s) == 1
Có một số cách ngắn hơn để gọi làm():
a := make([]int, 10)
// len(a) == cap(a) == 10
b := make([]int)
// len(b) == cap(b) == 0
Đó là tất cả tốt và tốt, nhưng những gì nếu bạn cần phải tăng chiều dài của lát vượt quá khả năng của nó? Để làm điều đó, bạn cần phân bổ một slice mới và sao chép nội dung của slice cũ sang slice mới. (Chức năng "sao chép" là một built-in.)
t := make([]int, len(s), 20)
copy(t, s)
Các Effective Go document mất ví dụ này một chút nữa, thực hiện một chức năng Append đó gắn thêm một miếng khác, thay đổi kích thước nó nếu cần thiết.
Lát được hỗ trợ bởi mảng; khi bạn thực hiện() một lát của một dung lượng cụ thể, một mảng dung lượng đó được phân bổ trong nền. Các slice có hiệu quả trở thành một "con trỏ thông minh" cho mảng đó. Nếu bạn chuyển slice đó (hoặc một subslice của slice đó) đến một hàm khác, nó sẽ được chuyển thành một con trỏ tới cùng một mảng đó. Điều này làm cho các slice phụ rất rẻ để tạo ra - đó là việc phân bổ mảng sao lưu đắt tiền.
Thư viện chuẩn Go bao gồm một số gói chứa - ví dụ: - loại bỏ sự cần thiết phải quản lý thủ công các lát cắt. Sử dụng lát cho tốc độ, và các lớp container phức tạp hơn để thuận tiện. (Nói vậy, tôi vẫn sử dụng lát cho hầu hết mọi thứ.)
Bạn có thể thắc mắc tại sao bạn cần phải giải quyết mọi rắc rối này. Sau khi tất cả, rất nhiều ngôn ngữ cung cấp mảng được điều chỉnh kích thước động như nguyên thủy. Lý do cho điều này là gắn liền với triết lý của Go. Các nhà thiết kế ngôn ngữ không cho biết chính sách phân bổ phù hợp cho chương trình của bạn là gì; thay vào đó, họ cung cấp cho bạn các công cụ bạn cần để xây dựng cấu trúc dữ liệu của riêng bạn.
chuyên sâu đọc: https://blog.golang.org/go-slices-usage-and-internals – user