Array, Slice and String in Go

Source:
(1)Arrays, slices (and strings): The mechanics of ‘append’(Must Read)
(2)Go Slices: usage and internals
(3)Slices from the ground up (Must Read)
(4)Are large slices more expensive than smaller ones?
(5)Go Data Structures
(6)Strings, bytes, runes and characters in Go
(7)Go wiki SliceTricks
Digest:
1. Arrays in Go have two relevant properties:
(1) They have a fixed size; [5]int is both an array of 5 ints and is distinct from [3]int.
(2) They are value types.
2. Go’s slice type differs from its array counterpart in two important ways:
(1) Slices do not have a fixed length. A slice's length is not declared as part of its type, rather it is held within the slice itself and is recoverable with the built-in function len.
(2) Assigning one slice variable to another does not make a copy of the slices contents. This is because a slice does not directly hold its contents. Instead a slice holds a pointer to its underlying array which holds the contents of the slice.
3. The slice header value:
The magic that makes a slice behave both as a value and a pointer is to understand that a slice is actually a struct type. ... This is important because unlike map and chan types slices are value types and are copied when assigned or passes as arguments to functions.
The slightly unusual nature of a Go slice variable is it's passed around as a value, not than a pointer. 90% of the time when you declare a struct in Go, you will pass around a pointer to values of that struct. This is quite uncommon, the only other example of passing a struct around as a value i can think of off hand is time.Time.
It is this exceptional behaviour of slices as values, rather than pointers to values, that can confuses Go programmer's understanding of how slices work. Just remember that any time you assign, subslice, or pass or return, a slice, you're making a copy of the three fields in the slice header; the pointer to the underlying array, and the current length and capacity.
4. Append: The built-in function:
Remember, since the slice header is always updated by a call to append, you need to save the returned slice after the call. In fact, the compiler won't let you call append without saving the result.
5. Nil Slice:
As should be clear, an empty slice can grow (assuming it has no-zero capacity), but a nil slice has no array to put values in and can never grow to hold even one element.
That said, a nil slice is functionally equivalent to a zero-length slice, even though it points to nothing. It has length zero and can be appended to, with allocation.
6. Strings:
Strings are actually very simple: they are just read-only slices of bytes with a bit of extra syntactic support from the language.
Because they are read-only, there is no need for a capacity (you can't grow them), but otherwise for most purposes you can treat them just like read-only slices of bytes.
The array underlying a string is hidden from view; there is no way to access its contents except through the string. That means that when we do either of these conversions, a copy of the array must be made. Go takes care of this, of course, so you don't have to. After either of these conversions, modifications to the array underlying the byte slice don't affect the corresponding string.
An important consequence of this slice-like design for strings is that creating a substring is very efficient. All that needs to happen is the creation of a two-word string header. Since the string is read-only, the original string and the string resulting from the slice operation can share the same array safely.
A historical note: The earliest implementation of strings always allocated, but when slices were added to the language, they provided a model for efficient string handling. Some of the benchmarks saw huge speedups as a result.
7. Conslusion:
To understand how slices work, it helps to understand how they are implemented. There is a little data structure, the slice header, that is the item associated with the slice variable, and that header describes a section of a separately allocated array. When we pass slice values around, the header gets copied but the array it points to is always shared.
Once you appreciate how they work, slices become not only easy to use, but powerful and expressive, especially with the help of the copy and append built-in functions.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值