Home  >  Article  >  Backend Development  >  An article briefly analyzing slices in Golang

An article briefly analyzing slices in Golang

青灯夜游
青灯夜游forward
2022-12-05 19:12:495895browse

This article will teach you about Golang and talk about slices (Slice) in the basics of Go language. I hope it will be helpful to you.

An article briefly analyzing slices in Golang

1. Definition of slice

We know from the previous section that because the length of the array is fixed and the length of the array belongs Part of the type, there are already three elements in array a, and we can no longer add new elements to array a. In js, it is normal for us to add elements to arrays and other operations. So what should we do with go? This will introduce our focus today - slicing. [Programming Tutorial Recommendation: Programming Tutorial]

Slice is a variable-length sequence of elements of the same type. It is a layer of encapsulation based on the array type. It is very flexible and supports automatic expansion. A slice is a reference type, and its internal structure contains address, length, and capacity. Slices are generally used to quickly operate on a collection of data.

The basic syntax for declaring a slice type is as follows:

var name []T

Among them,

  • name: represents the variable name
  • T: represents the element in the slice Type
func main() {
   // 声明切片类型
   var a []string              //声明一个字符串切片
   var b = []int{}             //声明一个整型切片并初始化
   var c = []bool{false, true} //声明一个布尔切片并初始化
   var d = []bool{false, true} //声明一个布尔切片并初始化
   fmt.Println(a)              //[]
   fmt.Println(b)              //[]
   fmt.Println(c)              //[false true]
   fmt.Println(a == nil)       //true
   fmt.Println(b == nil)       //false
   fmt.Println(c == nil)       //false
   // fmt.Println(c == d)   //切片是引用类型,不支持直接比较,只能和nil比较
}

2. Simple slice expression

The bottom layer of the slice is an array, so we can get the slice through the slice expression based on the array. low and high in the slicing expression represent an index range (left includes, right does not include), that is, 1<= is selected from array a in the following code The elements with index value <4 form slice s, the length of the obtained slice is = high-low, and the capacity is equal to the capacity of the underlying array of the obtained slice.

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	s := a[1:3]  // s := a[low:high]
	fmt.Printf("s:%v len(s):%v cap(s):%v\n", s, len(s), cap(s))
}



输出:
a[2:]  // 等同于 a[2:len(a)]
a[:3]  // 等同于 a[0:3]
a[:]   // 等同于 a[0:len(a)]

3. Complete slice expression

For arrays, pointers to arrays, or slice a (note that it cannot be a string) is supported Complete slicing expression

a[low : high : max]

The above code will construct a slice of the same type, same length and elements as the simple slicing expressiona[low: high]. Additionally, it sets the capacity of the resulting slice to max-low. Only the first index value (low) can be omitted in a full slicing expression; it defaults to 0.

func main() {
	a := [5]int{1, 2, 3, 4, 5}
	t := a[1:3:5]
	fmt.Printf("t:%v len(t):%v cap(t):%v\n", t, len(t), cap(t))
}

输出:
t:[2 3] len(t):2 cap(t):4

The conditions that a complete slice expression needs to satisfy are0 <= low <= high <= max <= cap(a), other conditions and simple slice expressions same.

4. Use the make() function to construct a slice

We have all created slices based on arrays. If we need to dynamically create a slice, we need to use The built-in make() function has the following format:

make([]T, size, cap)

Among them:

  • T: the element type of the slice
  • size: in the slice Number of elements
  • cap: capacity of the slice
func main() {
	a := make([]int, 2, 10)
	fmt.Println(a)      //[0 0]
	fmt.Println(len(a)) //2
	fmt.Println(cap(a)) //10
}

In the above code, 10 internal storage spaces of a have been allocated, but only 2 are actually used indivual. Capacity does not affect the number of current elements, so len(a) returns 2, and cap(a) returns the capacity of the slice.

5. Determine whether the slice is empty

The essence of a slice is to encapsulate the underlying array. It contains three pieces of information: the pointer of the underlying array and the length of the slice. (len) and the capacity of the slice (cap).

Slices cannot be compared. We cannot use the == operator to determine whether two slices contain all equal elements. The only legal comparison operation for slices is with nil. A slice of nil values ​​has no underlying array, and the length and capacity of a nil value slice are both 0. But we cannot say that a slice with a length and capacity of 0 must be nil, such as the following example:

var s1 []int         //len(s1)=0;cap(s1)=0;s1==nil
s2 := []int{}        //len(s2)=0;cap(s2)=0;s2!=nil
s3 := make([]int, 0) //len(s3)=0;cap(s3)=0;s3!=nil

To check whether the slice is empty, always use len( s) == 0 instead of s == nil.

6. Assignment copy of slice

The two variables before and after copying share the underlying array. Modification of one slice will affect the content of another slice. This requires special attention. Notice.

func main() {
	s1 := make([]int, 3) //[0 0 0]
	s2 := s1             //将s1直接赋值给s2,s1和s2共用一个底层数组
	s2[0] = 100
	fmt.Println(s1) //[100 0 0]
	fmt.Println(s2) //[100 0 0]
}

7. Slice traversal

The traversal method of slices is the same as that of arrays, and supports index traversal and for range traversal.

func main() {
	s := []int{1, 3, 5}

	for i := 0; i < len(s); i++ {
		fmt.Println(i, s[i])
	}

	for index, value := range s {
		fmt.Println(index, value)
	}
}

8. The append() method adds elements to the slice

The built-in function of Go languageappend()can dynamically add elements to the slice . You can add one element at a time, multiple elements, or elements from another slice (followed by...).

func main(){
	var s []int
	s = append(s, 1)        // [1]
	s = append(s, 2, 3, 4)  // [1 2 3 4]
	s2 := []int{5, 6, 7}  
	s = append(s, s2...)    // [1 2 3 4 5 6 7]
}

Zero-valued slices declared through var can be used directly in the append() function without initialization.

var s []ints = append(s, 1, 2, 3)

每个切片会指向一个底层数组,这个数组的容量够用就添加新增元素。当底层数组不能容纳新增的元素时,切片就会自动按照一定的策略进行“扩容”,此时该切片指向的底层数组就会更换。“扩容”操作往往发生在append()函数调用时,所以我们通常都需要用原变量接收append函数的返回值。

9.使用copy()函数复制切片

由于切片是引用类型,所以a和b其实都指向了同一块内存地址。修改b的同时a的值也会发生变化。

func main() {
	a := []int{1, 2, 3, 4, 5}
	b := a
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(b) //[1 2 3 4 5]
	b[0] = 1000
	fmt.Println(a) //[1000 2 3 4 5]
	fmt.Println(b) //[1000 2 3 4 5]
}

Go语言内建的copy()函数可以迅速地将一个切片的数据复制到另外一个切片空间中,copy()函数的使用格式如下:

copy(destSlice, srcSlice []T)

其中:

  • srcSlice: 数据来源切片
  • destSlice: 目标切片
func main() {
	// copy()复制切片
	a := []int{1, 2, 3, 4, 5}
	c := make([]int, 5, 5)
	copy(c, a)     //使用copy()函数将切片a中的元素复制到切片c
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1 2 3 4 5]
	c[0] = 1000
	fmt.Println(a) //[1 2 3 4 5]
	fmt.Println(c) //[1000 2 3 4 5]
}

10.从切片中删除元素

Go语言中并没有删除切片元素的专用方法,我们可以使用切片本身的特性来删除元素。

func main() {
	// 从切片中删除元素
	a := []int{30, 31, 32, 33, 34, 35, 36, 37}
	// 要删除索引为2的元素
	a = append(a[:2], a[3:]...)
	fmt.Println(a) //[30 31 33 34 35 36 37]
}

要从切片a中删除索引为index的元素,操作方法是a = append(a[:index], a[index+1:]...)

结束:

再次提醒,需要进技术交流群的同学,可以加我微信fangdongdong_25,需要进前端工程师交流群的备注“前端”,需要进go后端交流群的备注“go后端”

【相关推荐:Go视频教程

The above is the detailed content of An article briefly analyzing slices in Golang. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete