Go: Slice vs Array
Slice là một cấu trúc dữ liệu trong Go, nó được mô tả bởi một mảng và các thông tin về độ dài và sức chứa của mảng đó. Slice là một phần của mảng, nó cung cấp một cách để thao tác với một phần của mảng mà không cần sao chép toàn bộ mảng.
Mảng trong Go có độ dài cố định và không thể thay đổi sau khi được khai báo. Trong Go, mảng không được sử dụng phổ biến vì độ dài của mảng là một phần của kiểu dữ liệu, điều này giới hạn khả năng biểu diễn của mảng. Ví dụ, [3]int và [4]int là hai kiểu dữ liệu khác nhau.
Trái lại, slice rất linh hoạt và có thể mở rộng độ dài của nó theo nhu cầu. Kiểu và độ dài của slice không liên quan đến nhau.
Mảng là một phần liên tục trong bộ nhớ, trong khi slice thực chất là một cấu trúc dữ liệu bao gồm ba trường: con trỏ đến mảng, độ dài và sức chứa.
Cấu trúc dữ liệu của slice như sau:
Lưu ý rằng một mảng có thể được trỏ đến bởi nhiều slice cùng một lúc, do đó việc thay đổi một phần tử của một slice có thể ảnh hưởng đến các slice khác.
【Mở rộng 1】
[3]int
và [4]int
có cùng một kiểu dữ liệu không?
Không. Vì độ dài của mảng là một phần của kiểu dữ liệu, điều này khác với slice.
【Mở rộng 2】
Đoạn mã dưới đây sẽ in ra gì?
Kết quả:
s1
là một phần của slice
từ chỉ số 2 (đóng) đến chỉ số 5 (mở, thực tế chỉ lấy đến chỉ số 4), có độ dài 3 và sức chứa mặc định đến cuối mảng, là 8.
s2
là một phần của s1
từ chỉ số 2 (đóng) đến chỉ số 6 (mở, thực tế chỉ lấy đến chỉ số 5), có sức chứa đến chỉ số 7 (mở, thực tế chỉ lấy đến chỉ số 6), là 5.
Tiếp theo, thêm một phần tử 100 vào cuối s2
:
Sức chứa của s2
vừa đủ, nên phần tử mới được thêm trực tiếp. Tuy nhiên, điều này sẽ thay đổi phần tử tương ứng trong mảng gốc và s1
.
Tiếp theo, thêm một phần tử 200 vào cuối s2
:
Lần này, sức chứa của s2
không đủ, nên cần phải mở rộng. s2
sẽ tạo một mảng mới, sao chép các phần tử từ vị trí cũ sang vị trí mới và mở rộng sức chứa. Đồng thời, để đối phó với việc mở rộng sức chứa lần sau có thể cần, s2
sẽ để lại một số buffer
trong quá trình mở rộng, sức chứa mới sẽ là gấp đôi sức chứa cũ, tức là 10.
Cuối cùng, thay đổi phần tử tại chỉ số 2 của s1
:
Lần này chỉ ảnh hưởng đến phần tử tương ứng trong mảng gốc. Nó không ảnh hưởng đến s2
vì s2
đã đi xa rồi.
Một điểm nữa, khi in s1
, chỉ in ra số phần tử trong s1
. Nó không in ra toàn bộ mảng dù mảng có nhiều hơn 3 phần tử.