Golang Learning--Array (array) and slice (slice)

Source: Internet
Author: User
Tags readfile
This is a creation in Article, where the information may have evolved or changed.

The array type is often used in the process of using Golang. In the view Golang Official document, it is found that in the Golang language there is a slice type in addition to the array type. This slice type does not appear in other languages, so what type is this slice type? What is the difference between a slice and an array? Here's a story about arrays and slices in Golang.

First we look at the array:
An array in Golang is a data type that consists of fixed-length and fixed-object types. For example, the following:

a [4]inta[01a[0]// i == 1

A is an array of 4 elements of type int. Once a is declared, the number of elements is fixed and the number of elements does not change within the lifetime of a variable. At this point the type of a is [4]int, if there is also a B variable, for [5]int. Even if the two variables differ only by one element, the memory also occupies a completely different address allocation unit, and A and B are two completely different data types.

In Golang, once an array is defined, its internal elements are initialized. For example, accessing a[1] At this point is 0. So the initialization value of int is 0.

a[1]==0

The memory distribution of A is now the following situation:

In Golang, an array is a data entity object. In Golang when you use a, you represent the array of a again. In C, when a is used, it represents a pointer to the first element of the array. Please pay attention to this from the C-language students.

Why do we have to mention this? Because this is very important for the following explanation. Because a represents the entire array object, the additions and deletions to a are actually copies of the array object. In other words, the array in Golang is a copy of the value rather than a reference copy. If you want to manipulate the array itself, then manipulate the pointer to that object, which is to change the value copy to a reference copy.

In Golang, although the array is a built-in data type, "stiff" is not a good use. Therefore, Golang recommends using slices, which are more graceful and flexible than arrays.

Golang the slice is defined as: []t. T represents the slice element type. When different from the array, the slice does not need to specify the number of elements (length) when declaring. There are two ways to declare a slice:

letters := []string{"a""b""c""d"}

At first glance, the declarations of the array are very similar. However, when the array declaration is different, the slice declaration does not need to specify the number of elements. Golang, by contrast, is more of an alternative way of declaring: Using the built-in make function.

funcmakelencap) []T

When using the Make function, three parameters are required: T (slice element type), Len (number of slice elements), and cap (tile capacity). Typical usage is as follows:

var s []bytemake([]byte, 5, 5)// s == []byte{0, 0, 0, 0, 0}

When used in general, the capacity is often omitted and changed to:

make([]byte, 5)

When this omission is used, the capacity defaults to the element length.

Once a slice is declared, you can get the number of elements and the capacity of the slices by using the built-in Len function and the CAP function, as follows:

len(s) == 5cap(s) == 5

The reader may ask what is the relationship between the number of elements and the number of capacities? This question, we will talk about below, please be patient and look down.

A well-declared slice can be sliced again. Such as:

b := []byte{'g''o''l''a''n''g'}// b[1:4] == []byte{'o''l''a'as b

B is a slice that can be regenerated to a slice based on this slice by [n:m] left-open right-closed. , B[1:4] generates a new slice with a slice element range of 4.

[N:m] is also available in a number of shorthand ways, as shown in:

// b[:2] == []byte{'g''o'}// b[2:] == []byte{'l''a''n''g'}// b[:] == b

These are tiles-based slices that allow the generation of a slice based on an array in Golang, as follows:

x := [3]string{"Лайка""Белка""Стрелка"// a slice referencing the storage of x

After a slice is generated, you can use the same slice as you would with an array. For example, you can use subscript to access an element or to modify an element by subscript.

Some people will ask, so it seems that the slice is an indefinite number of arrays it? There's no difference?

Let's take a look at what's different about slices and arrays.

Slices are different from internal data structures, and arrays. Although there is almost no difference in the use of slices and arrays, the internal structure is quite different, and is the data structure of the slices:

There are three properties in the slice structure, namely the pointer to the first element, the shaping value of the number of elements saved and the number of saved capacity. As an example of the S-slice we started with, it's inside:

The pointer points to the first element of an array, and Len is the number of elements in this slice, which is 5. The CAP refers to the first element from the array to the last element of the array, which is also 5.

If we slice s two times, as follows:

s = s[2:4]

The situation will change, as follows:

Len=2 good understanding, because the new slice contains only the third and fourth elements of the original slice, so the number of elements is 2. But how does cap=3 understand? We mentioned above that the CAP refers to the number of the first element of the array to the last element of the array. Now the first element of the new slice starts with the third element of the original array, the original array has 5 elements, so the cap is the number of three elements of 3,4,5, so cap=3. The last pointer is very easy to understand, because the slice starts with the third element of the original array, so the pointer is a logical point to the third element.

In turn, if S=s[1:3]. Then the pointer points to the second element of the original array, len=2,cap=4.

With pointers, you should also be able to see that slices are not value copies, but reference copies. The operation on the slice affects the values in the original array, as follows:

d := []byte{'r''o''a''d'}e := d[2:] // e == []byte{'a''d'}e[1'm'// e == []byte{'a''m'}// d == []byte{'r''o''a''m'}

By explaining Len and cap above, you should understand that Len cannot be larger than the cap. If Len is larger than the cap, then a run-time exception is triggered. In the actual coding process, how to expand the tile? This leads to the next topic: How do I dynamically manipulate slices?

Dynamically manipulating slices, relying on two built-in functions copy and append. In other low-level languages, especially the C language. When the array is manipulated, it is often judged whether the current array has any remaining space, and if there is no space left, it will be reborn into a new array, and then the old array is copied to the new array. The code resembles the following:

声明t数组fori{        t[i] = s[i]}s = t

In Golang, readers can do the same. But Golang, after all, is a high-level language, it has built-in copy function, you can save some of the loop assignment. The code for using the copy function is as follows:

//func copy(dst, src []T) intmake([]bytelen(s), (cap(s)+1)*2)copy(t, s)s = t

When the copy is finished, we should consider whether the original array space is free, and the code is as follows:

funcAppendbyte (Slice []byte, data ...byte) []byte{m: =Len(slice) N: = m +Len(data)ifn >Cap(Slice) {//If necessary, reallocate        //Allocate double what ' s needed, for the future growth.Newslice: = Make([]byte, (n+1) * *)Copy(Newslice, slice) slice = newslice} slice = Slice[0: n]Copy(Slice[m:n], data)returnSlice

This way, when we add data to the slice again, we don't have to consider the overflow situation, as follows:

p := []byte{23571113)// p == []byte{2, 3, 5, 7, 11, 13}

Golang because adding data to a slice is a frequently used feature, it provides the APPEND function to do the work for us.

The following is a declaration of the APPEND function:

funcappend(s[]Tx ...T[]T

When using the Append function, the APPEND function will determine if the destination slice has any remaining space, and if there is no space left, it will automatically expand twice times the space. Here are a few examples of using the APPEND function:

a1)// a == []int{0}a = append(a123)// a == []int{0, 1, 2, 3}

The Append function can not only add elements, but also add slices, as follows:

a := []string{"John""Paul"}b := []string{"George""Ringo""Pete"}a = append(a"append(a, b[0], b[1], b[2])"a == []string{"John""Paul""George""Ringo""Pete"}

Here is an actual code that, by providing the judging function, only adds the required elements, as follows:

new slice holding only// the elements of s that satisfy f()func Filter(s []intfunc(intbool) []int {    var p []int// == nil    forrange s {        if fn(v) {            append(p, v)        }    }    return p}

When you use slices in Golang, Golang will pre-load the array that the slices point to in memory. So there may be a situation where we only need a fraction of the data in the array, but Golang loads all the data. For example, the following example:

var digitRegexp = regexp.MustCompile("[0-9]+")funcstring) []byte {    b, _ := ioutil.ReadFile(filename)    return digitRegexp.Find(b)}

We just want to find the data in the given file that matches the regular expression, but we want to load the entire file into memory. The data will not be cleared out of memory until the returned slices are explicitly not used. To avoid this problem, it is recommended that you keep only useful data by slicing copies, and discard useless data as follows:

funcstring) []byte {    b, _ := ioutil.ReadFile(filename)    b = digitRegexp.Find(b)    make([]bytelen(b))    copy(c, b)    return c}

In this way, only a small amount of data from C will be present in the final memory. The pre-loaded file data is freed by the garbage collector.

Okay, here's the similarities and differences between arrays and slices in the Golang language. If the explanation has the wrong place, welcome the message discussion.

Copyright NOTICE: This article for Bo Master original article, without Bo Master permission not reproduced. Please pay attention to the original http://blog.csdn.net/vikings_1001

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.