[Go] arrays, strings and slice

Arrays, strings and slice

Go language arrays, strings and slice three data structures are closely related. These three types of data, the underlying raw data memory has the same structure. Although the elements of the array can be modified, but the array itself is a function of mass participation and assignments are a way of copying the entire process. String assignment just copied data and the corresponding address length, without causing the underlying data replication.

Array

An array is a sequence of particular type elements composed of a fixed length, it may be composed of an array of zero or more elements. Length of the array is part of an array type. Because the length of the array is a portion of the array type, an array of different lengths or different types of data are composed of different types, and therefore rarely used directly, in Go the array (the array of different lengths since different types can not be directly assigned). Type and array corresponds to a slice, slice is a sequence can dynamically grow and shrink, the slice function more flexible, but to understand how the thing is to understand the array slice.

Defined way
var a [3]int // 定义长度为3的int型数组, 元素全部为0
var b = [...]int{1, 2, 3} // 定义长度为3的int型数组, 元素为 1, 2, 3
var c = [...]int{2: 3, 1: 2} // 定义长度为3的int型数组, 元素为 0, 2, 3
var d = [...]int{1, 2, 4: 5, 6} // 定义长度为6的int型数组, 元素为 1, 2, 0, 0, 5, 6

The first way is to define a basic array variable, the length of the array explicitly specified, each element of the array are initialized to zero values.

The second way to define an array, the initialization value can be specified in the definition of all elements of the time sequence, the length of the array is initialized automatically calculated based on the number of elements.

A third way is to initialize the element of the index array manner, and therefore the initialization values ​​of the elements in order of appearance more casual. This initialization mode and map [int] Type similar types of initialization syntax. The maximum length of the array index appears to prevail, there is no clear elements initialized with a value of 0 is still initializing.

The fourth embodiment is a mixture of the second and third embodiment of the initialization, the initialization sequence using the first two elements, one element of the third and fourth initialization value of zero, the fifth through the index of the initialization element, with the last element in the front after the initialization sequence using the fifth element.

Arrays and pointers

Go language is an array value semantics. I.e. an array variable represents the entire array, it is not a pointer to the first element of the implicit point (such as arrays in C), but a full value. When an array variable is assigned or to be delivered, you will actually copy the entire array. If the array is larger, then the assignment of the array will have greater overhead. To avoid the overhead of copying the array to bring, you can pass a pointer to an array, but the array is not a pointer array.

var a = [...]int{1, 2, 3} // a 是一个数组
var b = &a // b 是指向数组的指针
fmt.Println(a[0], a[1]) // 打印数组的前2个元素
fmt.Println(b[0], b[1]) // 通过数组指针访问数组元素的方式和数组类似

The array can be viewed as a special structure, the structure of the field names corresponding to the index of the array, while the number of members of the body structure is fixed. Len built-in functions may be used to calculate the length of the array, cap functions may be used to calculate the capacity of the array. For array types, however, result return len and cap functions is always the same, are corresponding to the length of the array type.

Traversal
for i := range a {
    fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
    fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
    fmt.Printf("c[%d]: %d\n", i, c[i])
}

Using an iterative manner for range performance may be better, because this iterative array bounds can ensure the situation does not appear, judgment can save each iteration of the subscript out of bounds when access to the array elements.

String

A string is a sequence of bytes can not be changed, the string is typically used to contain a human-readable text data. And the array is different, the elements of the string can not be modified, is a read byte array. While each string is also fixed, but is not a part of the length of the string type string.

Go substructure definition language strings in the reflect.StringHeader:

type StringHeader struct {
    Data uintptr
    Len int
}

String structure consists of two information: a first string points to the underlying array of bytes, the second byte is the length of the string.

In fact, the string is a structure, so the assignment of the string is copying process reflect.StringHeader structure.

Although not string sections, but supports the slicing operation, slices of different positions of the bottom also with a memory data access (because the string is read-only, the same string literals usually correspond to the same string constant):

s := "hello, world"
hello := s[:5]
world := s[7:]
s1 := "hello, world"[:5]
s2 := "hello, world"[7:]

slice

Structure definition slice, reflect.SliceHeader:

type SliceHeader struct {
    Data uintptr
    Len int
    Cap int
}
Defined way
var (
    a []int // nil切片, 和 nil 相等, 一般用来表示一个不存在的切片
    b = []int{} // 空切片, 和 nil 不相等, 一般用来表示一个空的集合
    c = []int{1, 2, 3} // 有3个元素的切片, len和cap都为3
    d = c[:2] // 有2个元素的切片, len为2, cap为3
    e = c[0:2:cap(c)] // 有2个元素的切片, len为2, cap为3
    f = c[:0] // 有0个元素的切片, len为0, cap为3
    g = make([]int, 3) // 有3个元素的切片, len和cap都为3
    h = make([]int, 2, 3) // 有2个元素的切片, len为2, cap为3
    i = make([]int, 0, 3) // 有0个元素的切片, len为0, cap为3
)
Traversal
for i := range a {
    fmt.Printf("a[%d]: %d\n", i, a[i])
}
for i, v := range b {
    fmt.Printf("b[%d]: %d\n", i, v)
}
for i := 0; i < len(c); i++ {
    fmt.Printf("c[%d]: %d\n", i, c[i])
}

When slice itself or assigned transmission parameters, and the operation is similar to the pointer array, just copy a slice header information (reflect.SliceHeader), and the underlying data is not copied.

Add to
var a []int
a = append(a, 1) // 追加1个元素
a = append(a, 1, 2, 3) // 追加多个元素, 手写解包方式
a = append(a, []int{1,2,3}...) // 追加一个切片, 切片需要解包

Guess you like

Origin www.cnblogs.com/Ryan16231112/p/12315363.html