go从0到1项目实战体系六:slice切片

1. slice:

go 复制代码
①. 基础:
   a. 切片是指向数组的一个引用,因此切片是引用类型.
   b. 切片的长度可以改变.因此,切片是一个可变的数组.
   c. 切片遍历方式和数组一样,可以用len()求长度.

②. 定义:
   var 变量名 []类型         // 与数组的区别是没有写长度
   a. var arr []string

③. len是长度、cap是容量:
   a. cap表示slice最大的容量.
   b. 大小关系:
      0 <= len(slice) <= (array:slice引用的数组).

2. 通过数组创建切片:

go 复制代码
var slice []int = arr[start:end]        // 包含数组的start到end之间的元素(但不包含end)
var slice []int = arr[0:end]            // 简写var slice []int = arr[:end]
var slice []int = arr[start:len(arr)]   // 从start到末尾的所有元素,简写var slice []int = arr[start:]
var slice []int = arr[0, len(arr)]      // 数组的所有元素,简写var slice []int = arr[:]
slice = slice[:len(slice)-1]            // 切片最后一个元素去掉

(1). 数组创建切片的内存布局:

go 复制代码
①. 如上图数据结构:
   [ptr指针地址]  [len长度]  [cap]
   类似:
   type slice struct {
      ptr *[5]int     =>  指向一个数组
      len
      cap
   }

②. 验证最下面切片的ptr地址是指向数组的第1个元素的地址:
   var a = [5]int{1, 2, 3, 4, 5}
	b := a[1:5]
	fmt.Println(b)                     // [2 3 4 5]
	fmt.Printf("%p\n", b)              // 0xc000076128
   fmt.Println(&a[1])                 // 0xc000076128

3. 通过make创建切片:

go 复制代码
var a []type = make([]type, len)
a := make([]type, len)
a := make([]type, len, cap)

(1). make创建切片的内存布局:

①. 少了定义数组的过程,只不过它的底层内部创建了一个数组.
②. 两种底层都是一样在操作数组.

4. 内置函数append操作切片:

go 复制代码
(1). 两个切片合并:
var a = []int{1, 2, 3}
var b = []int{4, 5, 6}
a = append(a, b...)
fmt.Println(a)                             // [1 2 3 4 5 6]

(2). 切片是动态的长度,如果超过固定的数组长度,会发生什么变化?
var a = [5]int{1, 2, 3, 4, 5}
b := a1[1:5]
fmt.Println(b)                                  // [2 3 4 5]
fmt.Printf("%p\t%p\n", b, &a[1])                // 0xc00006c158    0xc00006c158
fmt.Printf("len:%d\tcap:%d\n", len(b), cap(b))  // len:4   cap:4
b = append(b, 6)                                // 多次追加后,导致切片的长度大于a数组的固定长度
fmt.Printf("len:%d\tcap:%d\n", len(b), cap(b))  // len:5   cap:8
b = append(b, 7)
fmt.Println(a)                                  // [1 2 3 4 5]
fmt.Println(b)                                  // [2 3 4 5 6 7]
fmt.Printf("%p\t%p\n", b, &a[1])                // 0xc00006e0c0    0xc00006c158
注:
①. 系统底层会将数组重新拷贝一份,重新生成一个新的数组指向.
②. 当追加超过cap时,自动会变成一倍容量:4 -> 8.

5. 切片拷贝:

go 复制代码
s1 := []int{1, 2, 3, 4, 5}
s2 := make([]int, 1)
copy(s2, s1)
fmt.Println(s2)                  // [1],因为s2的cap是1.

s3 := []int{1, 2, 3}
s3 = append(s3, s2...)
s3 = append(s3, 4, 5, 6)

6. string原理:

string底层就是一个byte的数组,因此,也可以进行切片操作.

go 复制代码
str := "helloworld"
a := str[0:5]
fmt.Println(a)                // hello
b := str[5:]
fmt.Println(b)                // world

(1). string的底层布局:

①. 字符串是由多个字符组成,字符串不能修改(不可变的).
   a[0] = 'a'                 // 报错
②. [ptr指针地址]  [len长度]
   ptr指针指向一个byte数组

(2). 如何改变string中的字符值?

string本身是不可变的,因此要改变string中字符,需要如下操作:

go 复制代码
str := "helloworld"
s := []byte(str)              // 定义为[]rune(str)即可解决中文乱码问题
s[0] = 'o'
str = string(s)
fmt.Pintln(str)               // oelloworld

7. 排序和查找操作:

排序操作主要在sort包中

go 复制代码
import("sort")

①. sort.Ints:对整数进行排序.
   var a = [...]int{2, 5, 3, 1, 7}
   // 不能直接传a,是一个数组,值类型,就算里面排序好了,外面还是没有排序.要传一个切片.
   sort.Ints(a[:])

②. sort.Strings:对字符串进行排序.
   var a = [...]string{"abc", "ee", "ABC", "EFG", "vcd"}
   sort.Strings(a)

③. sort.Float64s:对浮点数进行排序.
   var a = [...]float64{20.88, 521.10, 56.20, 63.10}
   sort.Float64(a)

(1). 用serach方法查找,必须是排好序的:

go 复制代码
①. sort.SearchInts(a []int, b int):从数组a中查找b.
   var a = [...]int{2, 5, 3, 1, 7}
   sort.Ints(a[:])
   sort.SearchInts(a, 5)       // 前提a必须有序

②. sort.SearchFloats(a []float64, b float64):从数组a中查找b

③. sort.SearchStrings(a []string, b string) 从数组a中查找b
相关推荐
程序员爱技术41 分钟前
Vue 2 + JavaScript + vue-count-to 集成案例
前端·javascript·vue.js
m0_571957582 小时前
Java | Leetcode Java题解之第543题二叉树的直径
java·leetcode·题解
并不会2 小时前
常见 CSS 选择器用法
前端·css·学习·html·前端开发·css选择器
衣乌安、2 小时前
【CSS】居中样式
前端·css·css3
兔老大的胡萝卜2 小时前
ppk谈JavaScript,悟透JavaScript,精通CSS高级Web,JavaScript DOM编程艺术,高性能JavaScript pdf
前端·javascript
低代码布道师2 小时前
CSS的三个重点
前端·css
耶啵奶膘3 小时前
uniapp-是否删除
linux·前端·uni-app
魔道不误砍柴功4 小时前
Java 中如何巧妙应用 Function 让方法复用性更强
java·开发语言·python
NiNg_1_2344 小时前
SpringBoot整合SpringSecurity实现密码加密解密、登录认证退出功能
java·spring boot·后端
闲晨4 小时前
C++ 继承:代码传承的魔法棒,开启奇幻编程之旅
java·c语言·开发语言·c++·经验分享