1, Array array
Go language array is a fixed length sequence, and its internal elements generally limit the same type. The array is the underlying structure of the slice.
//Create array 1: assignment after declaration var arr1 [3]int arr1[0] = 0 arr1[1] = 1 arr1[2] = 2 //Create array 2: create and initialize arr2 := [3]int{1, 3, 5} //Create array 3: automatically calculate array length arr3 := [...]int{2, 4, 6, 8, 10} //len() is a built-in function used to obtain the length of arrays, slices, strings, channel s, etc var count = len(arr3) fmt.Printf("Type is%T,Value is%v,The number of elements is%d\n", arr3, arr3, count) //The type is [6]int, the value is [1 2 3 4 5 6], and the number of elements is 6 //Declare a two-dimensional array of two rows and three columns var grid [2][3]int grid[0] = [3]int{1,3,5} grid[1] = [3]int{2,4,6} fmt.Println(grid) //[[1 3 5] [2 4 6]] //Traversal array for index, value := range arr1 { fmt.Println(index, " ", value) } //0 0 //1 1 //2 2 //3 3 //4 4
2, Slice slice
1. Slice declaration and initialization
//array[start:end] intercepts a fragment with the subscript [start,end) from the array to form a slice //Start stands for the start subscript. If not written, the default stands for cutting from scratch //End stands for the end subscript (not included in itself). If it is not written, it will be intercepted to the end by default func BaseSlice01() { //Declare and initialize an array var arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7} //Create slices based on arrays slice1 := arr[2:5] slice2 := arr[:5] slice3 := arr[6:] slice4 := arr[:] fmt.Printf("arr Type is%T,Value is%v\n", arr, arr) //The arr type is [8]int and the value is [0 1 2 3 4 5 6 7] fmt.Printf("slice1 Type is%T,Value is%v\n", slice1, slice1) //slice1 type is [] int, value is [2 3 4] fmt.Printf("slice2 Type is%T,Value is%v\n", slice2, slice2) //slice2 type is [] int, value is [0 1 2 3 4] fmt.Printf("slice3 Type is%T,Value is%v\n", slice3, slice3) //slice3 type is [] int and value is [6 7] fmt.Printf("slice4 Type is%T,Value is%v\n", slice4, slice4) //slice4 type is [] int, value is [0 1 2 3 4 5 6 7] }
2. Slice additional elements
//Append element to slice func BaseSlice02() { slice := []int{1, 2, 3, 4} slice = append(slice, 5, 6) //Append multiple elements directly slice = append(slice, []int{7, 8, 9}...) //To add an element in another slice, you need to "flatten" the added element, followed by that will do fmt.Printf("slice1 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice, slice, len(slice), cap(slice)) slice1 Type is[]int,Value is[1 2 3 4 5 6 7 8 9],Length 9,Capacity 16 //Traversal slice for _, v := range slice { fmt.Print(v, " ") } //1 2 3 4 5 6 7 8 9 }
3. Slice capacity expansion
//cap(slice) obtains the capacity of the slice //At the beginning of creation, the capacity is equal to the length //When expanding, once the capacity cannot meet the needs, it will be expanded by doubling the capacity //Pay attention to the change of stack address during slice expansion func BaseSlice03() { arr := [4]int{1, 2, 3, 4} fmt.Printf("arr Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", arr, arr, len(arr), cap(arr), &arr) slice := arr[:] fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 5) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 6) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 7) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 8) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 9) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) slice = append(slice, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20) fmt.Printf("slice Type is%T,Value is%v,Count Reg%d,Capacity%d,Address is%p\n", slice, slice, len(slice), cap(slice), slice) } //The arr type is [4]int, the value is [1 2 3 4], the length is 4, the capacity is 4, and the address is 0xc00011e000 //slice type is [] int, value is [1 2 3 4], length is 4, capacity is 4, and address is 0xc00011e000 //slice type is [] int, value is [1 2 3 4 5], length is 5, capacity is 8, and address is 0xc000126040 //slice type is [] int, value is [1 2 3 4 5 6], length is 6, capacity is 8, and address is 0xc000126040 //slice type is [] int, value is [1 2 3 4 5 6 7], length is 7, capacity is 8, and address is 0xc000126040 //slice type is [] int, value is [1 2 3 4 5 6 7 8], length is 8, capacity is 8, and address is 0xc000126040 //slice type is [] int, value is [1 2 3 4 5 6 7 8 9], length is 9, capacity is 16, and address is 0xc00000c0180 //slice type is [] int, value is [1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20], length is 20, capacity is 32, and address is 0xc00012c000 //Each slice expansion is a capacity multiplication, and the pointer address of its slice head changes. It can be seen that another memory is opened and copied during multiplication
4. Merger
/*Merge another slice*/ func BaseSlice04() { slice := []int{1, 2, 3, 4} fmt.Printf("slice1 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice, slice, len(slice), cap(slice)) sli := []int{7, 8, 9} slice = append(slice, sli...) //Pay attention to "flattening" during Merger fmt.Printf("slice1 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice, slice, len(slice), cap(slice)) } //slice1 type is [] int, value is [1 2 3 4], length is 4 and capacity is 4 //slice1 has a type of [] int, a value of [1 2 3 4 7 8 9], a length of 7 and a capacity of 8
5. Use the make() function to create slices
/*Creates a slice of the specified length and capacity*/ func BaseSlice05() { //Create an empty slice slice1 := make([]int, 0) fmt.Printf("slice1 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice1, slice1, len(slice1), cap(slice1)) //slice1 type is [] int, value is [], length is 0 and capacity is 0 //Creates an empty slice, but specifies the capacity slice2 := make([]int, 0, 5) fmt.Printf("slice2 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice2, slice2, len(slice2), cap(slice2)) //slice2 is of type [] int, value [], length 0 and capacity 5 //Create a slice with a length of 3 and a capacity of 5. The elements of the default length are initialized to zero slice3 := make([]int, 3, 5) fmt.Printf("slice3 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice3, slice3, len(slice3), cap(slice3)) //slice3 is of type [] int, value [0], length 3 and capacity 5 //Create a slice with a length of 5. The elements of the default length are initialized to zero. When the capacity is not specified, the capacity value is equal to the length value slice4 := make([]int, 5) fmt.Printf("slice4 Type is%T,Value is%v,Count Reg%d,Capacity%d\n", slice4, slice4, len(slice4), cap(slice4)) //slice4 is of type [] int, value [0], length 5 and capacity 5 }
6. Delete slice element
go has no built-in slice deletion function, so deleting elements requires traversing slices
//Delete slice element func RmSliceElement(slice []interface{}, index int) []interface{} { if index > len(slice)-1 { panic("index out of range") } for _, v := range slice { //If it is the last element if index == len(slice)-1 { return slice[:index] } //If it's an intermediate element if v == slice[index] { return append(slice[:index], slice[index+1:]...) } } return nil }
3, Map map
1.map creation
//Create and initialize m1 := map[string]string{ "name": "fun", "age": "18", "gender": "male", } //Create an empty map with a length of 5 and allocate memory m2 := make(map[string]int,5) //Only one map is declared and no memory is allocated var m3 map[string]int fmt.Printf("m1:%v,Address is%p\n", m1,m1) fmt.Printf("m2:%v,Address is%p\n", m2,m2) fmt.Printf("m3:%v,Address is%p\n", m3,m3) //m1:map[age:18 gender:male name:fun], address 0xc00008e480 //m2:map [], address 0xc00008e4b0 //m3:map [], address 0x0
2.map traversal and access value
//ergodic m := map[string]string{ "name": "fun", "age": "18", "gender": "male", } for key, val := range m { fmt.Printf("Key:%s,Value:%v\n", key, val) } //Key:name,Value:fun //Key:age,Value:18 //Key:gender,Value:male //Access a key value name := m["name"] fmt.Printf("name:%v\n", name) //name:fun //Access a key that does not exist names := m["names"] fmt.Printf("names:%v\n", names) //names: //Access with verification if a, ok := m["name"]; !ok { fmt.Println("key is not exist!") } else { fmt.Println(a) }
3. Delete map element
delete() is a built-in function, which is only valid for map
func BaseMap03() { m := map[string]string{ "name": "fun", "age": "18", "gender": "male", } fmt.Printf("m: %v\n", m) delete(m, "age") fmt.Printf("m: %v\n", m) } //m: map[age:18 gender:male name:fun] //m: map[gender:male name:fun]
4. Use of multidimensional map
//Use of multidimensional map func BaseMap04() { //Declare the structure of a two-dimensional map var ms = make(map[string]map[string]int, 3) fmt.Printf("ms:Type:%T, Value: %v, Len:%d, Address:%p\n", ms, ms, len(ms), ms) //Internal initialization for 2D map ms["a"] = make(map[string]int, 4) ms["b"] = make(map[string]int, 5) ms["c"] = make(map[string]int, 6) fmt.Printf("ms:Type:%T, Value: %v, Len:%d, Address:%p\n", ms, ms, len(ms), ms) ms["d"] = make(map[string]int, 7) fmt.Printf("ms:Type:%T, Value: %v, Len:%d, Address:%p\n", ms, ms, len(ms), ms) //Assignment: assignment can only be performed after internal initialization of two-dimensional array //Otherwise, panic: assignment to entry in nil map is reported ms["a"]["aa"] = 1 ms["a"]["bb"] = 2 ms["a"]["cc"] = 3 fmt.Printf("ms:Type:%T, Value: %v, Len:%d, Address:%p\n", ms, ms, len(ms), ms) //[1]ms:Type:map[string]map[string]int, Value: map[], Len:0, Address:0xc000104300 //[2]ms:Type:map[string]map[string]int, Value: map[a:map[] b:map[] c:map[]], Len:3, Address:0xc000104300 //[3]ms:Type:map[string]map[string]int, Value: map[a:map[] b:map[] c:map[] d:map[]], Len:4, Address:0xc000104300 //[4]ms:Type:map[string]map[string]int, Value: map[a:map[aa:1 bb:2 cc:3] b:map[] c:map[] d:map[]], Len:4, Address:0xc000104300 }
4, About make() and new() functions
1.make()
Go has a built-in function to create slice, map and channel chan, that is, make().
Usage:
func make(Type, size IntegerType) Type
According to official documents:
- Parameter 1 is a type, not a value, and the return type is the same as its parameter
- Parameter 2 different types of parameters
Slice: size specifies its length. The capacity of the slice is equal to its length. Slicing supports the second integer argument, which can be used to specify different capacities; It must not be less than its length, so make([]int, 0, 10) will allocate a slice with length of 0 and capacity of 10.
Mapping: the creation of the initial allocation depends on size, but the resulting mapping length is 0. Size can be omitted, in which case a small starting size will be allocated.
Channel: the cache of the channel is initialized according to the specified cache capacity. If the size is zero or omitted, the channel is uncached.
2.new()
Usage:
func new(Type) *Type
The built-in function new allocates memory. Its first argument is a type, not a value. Its return value is a pointer to the newly assigned zero value of the type.
3. Difference between two functions
- make() is specially used to create slices, maps and channels, allocate memory for them and initialize zero value. The returned slices, maps and channels are naturally pointer addresses.
- new() generally allocates memory for creating any type other than the built-in reference type, but does not initialize data. It only sets the memory to zero and returns the * T pointer address. It is generally used to create array or struct value types. Of course, you can also use it to create basic data types and return pointer addresses.