2017-01-16 19 views
5

Sự khác biệt giữa nắp và len của một lát trong golang là gì?cap vs len của slice trong golang

Theo định nghĩa:

Một lát có cả chiều dài và dung lượng.

Độ dài của một lát là số phần tử chứa trong đó.

Dung lượng của một lát là số phần tử trong mảng cơ bản, tính từ phần tử đầu tiên trong lát cắt.

x := make([]int, 0, 5) // len(b)=0, cap(b)=5 

Len có phải là giá trị không null không?

+2

Bạn đã thực hiện ngay cả một số tiền tối thiểu của nghiên cứu trước khi yêu cầu? Chỉ googling cho các từ khóa chắc chắn sẽ mang lại [điều này đi về bài viết về chủ đề] (https://blog.golang.org/go-slices-usage-and-internals) giải thích tất cả những gì bạn hỏi về. – kostix

Trả lời

0

Bạn đã trả lời câu hỏi của mình - độ dài của mảng cơ bản trong một lát không nhất thiết giống với số phần tử chứa mảng.

0

Từ source code:

// The len built-in function returns the length of v, according to its type: 
// Array: the number of elements in v. 
// Pointer to array: the number of elements in *v (even if v is nil). 
// Slice, or map: the number of elements in v; if v is nil, len(v) is zero. 
// String: the number of bytes in v. 
// Channel: the number of elements queued (unread) in the channel buffer; 
// if v is nil, len(v) is zero. 
func len(v Type) int 

// The cap built-in function returns the capacity of v, according to its type: 
// Array: the number of elements in v (same as len(v)). 
// Pointer to array: the number of elements in *v (same as len(v)). 
// Slice: the maximum length the slice can reach when resliced; 
// if v is nil, cap(v) is zero. 
// Channel: the channel buffer capacity, in units of elements; 
// if v is nil, cap(v) is zero. 
func cap(v Type) int 
15

Một lát là một khái niệm trừu tượng mà sử dụng một mảng trong chăn.

cap cho bạn biết dung lượng của mảng cơ bản. len cho bạn biết có bao nhiêu mục trong mảng.

Sự trừu tượng hóa slice trong Go rất đẹp vì nó sẽ thay đổi kích thước mảng bên dưới cho bạn, cộng với mảng Go không thể thay đổi kích thước để lát hầu như luôn được sử dụng thay thế.

Ví dụ:

s := make([]int, 0, 3) 
for i := 0; i < 5; i++ { 
    s = append(s, i) 
    fmt.Printf("cap %v, len %v, %p\n", cap(s), len(s), s) 
} 

Will ra một cái gì đó như thế này:

cap 3, len 1, 0x1040e130 
cap 3, len 2, 0x1040e130 
cap 3, len 3, 0x1040e130 
cap 8, len 4, 0x10432220 
cap 8, len 5, 0x10432220 

Như bạn có thể nhìn thấy một lần khả năng được đáp ứng, append sẽ trở lại một lát mới với công suất lớn hơn. Trong lần lặp thứ tư, bạn sẽ thấy một dung lượng lớn hơn và một địa chỉ con trỏ mới.

Play example

Tôi nhận ra rằng mình đã không hỏi về mảng và thêm nhưng họ là khá căn bản trong việc tìm hiểu lát và lý do cho các lệnh nội trú.

+0

Câu trả lời hay. OP có thể không quan tâm nữa, nhưng tôi có thể thấy điều này hữu ích cho nhiều người có thể tìm thấy nó trên đường. –

+0

@RandyHoward Cảm ơn, tôi đánh giá cao điều đó. Tôi thấy rằng địa chỉ con trỏ thay đổi là khá quan trọng. – jmaloney

+0

@jmaloney. Điều này rất hữu ích. Một điều tôi vẫn còn gặp khó hiểu là giá trị nil cho mảng và lát là số không (không phải nil hoặc null), làm thế nào chiều dài có thể thực sự khác với dung lượng. Không nên mỗi phần tử trong một lát dung lượng 3 có {1,0,0} trong lần lặp đầu tiên ... cho len là 3 không 1? Ý tôi là nếu nó chỉ là quy ước, tôi không hiểu logic trong quy ước đó. Tôi chỉ thiếu một cái gì đó hoặc tôi nên chấp nhận nó như là? –

Các vấn đề liên quan