当前位置: 首页> 娱乐> 明星 > 成都网页制作一般多少钱_免费项目进度管理软件_加盟教育培训哪个好_百度首页优化

成都网页制作一般多少钱_免费项目进度管理软件_加盟教育培训哪个好_百度首页优化

时间:2025/7/19 4:40:24来源:https://blog.csdn.net/Coffeemaker88/article/details/144254854 浏览次数:0次
成都网页制作一般多少钱_免费项目进度管理软件_加盟教育培训哪个好_百度首页优化

切片

在 Golang 当中实际上很少会用到数组,大部分情况下会直接使用切片(slices)。

Golang 当中的切片与 Python 当中的切片非常的相似(左开右闭区间),它是 array 的一个 view(视图),因此对切片进行的修改实际上会直接修改对应的 array。

一段切片的声明如下:

arr = [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
s1 = arr[2:6]	// 2, 3, 4, 5

一段完整的用法展示如下:

package mainimport "fmt"func updateSlice(s []int) {s[0] = 100
}func main() {/*Go 当中很少使用数组实际上更常使用的是切片(slice)*/arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}fmt.Println("arr[2:6] =", arr[2:6]) // 左开右闭区间fmt.Println("arr[:6] =", arr[:6])   // 左开右闭区间s1 := arr[2:]fmt.Println("s1 =", s1) // 左开右闭区间s2 := arr[:]            // 相当于直接将数组转为 slicefmt.Println("s2", s2)   // 左开右闭区间// slice 是对 array 的 view(视图)fmt.Println("After updateSlice(s1)")updateSlice(s1)fmt.Println("s1 =", s1)fmt.Println("arr =", arr) // 由于 s1 是对 array 的 view// 因此 array 的值也被修改了fmt.Println("After updateSlice(s2)")updateSlice(s2)fmt.Println("s2 =", s2)fmt.Println("arr =", arr)// slice 还有一个操作叫 reslice// 此时 s2 是一个 slicefmt.Println("Reslice")fmt.Println(s2)s2 = s2[:5]fmt.Println(s2)s2 = s2[2:]fmt.Println(s2)
}

切片的特性

以下例为例:

package mainimport "fmt"func main() {fmt.Println("Extending Slice: ")arr := [...]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}fmt.Println("arr =", arr)s1 := arr[2:6] // [2, 3, 4, 5]s2 := s1[3:5]  // [5, 6]fmt.Println("s1 =", s1)fmt.Println("s2 =", s2) // 不会报错, s2 仍然取得出来/* 为了理解上述行为为什么是合法的, 涉及到 Slice 的拓展知识slice 是对 array 的 view, 意味着 slice 知道底层的array, 因此 s2 仍然能取出底层 array 对应的值.我们称上述特性为 slice 的可拓展性.*//* slice 的底层实现由 ptr/len/cap 构成- ptr 指向 slice 第一个元素的地址;- len 指向 slice 的长度;- cap 为 capacity 的缩写, 表明 slice 至多可以向后扩展的长度注意: slice 不可以向前拓展.具体的扩展方法: s[i] 不可以超越 len(s), 向后扩展不能超过 cap(s) */fmt.Printf("s1=%v, len(s1)=%d, cap(s1)=%d\n", s1, len(s1), cap(s1))fmt.Printf("s1=%v, len(s2)=%d, cap(s2)=%d\n", s2, len(s2), cap(s2))
}

注意到,可以使用 len 来获取当前切片当中存储元素的长度。可以使用 cap 得到当前切片的最大容量,如果当前切片与某个数组绑定(即,切片为数组的视图),那么从切片的起始位置开始(比如第二个位置)到数组的最大位置(比如数组为{0, 1, 2, 3, 4, 5, 6,7 },切片为{2, 3, 4, 5})是切片的 cap(2, 3, 4, 5, 6, 7),切片可以取 cap 内的值,正如上例所示。

我个人认为这不是一个很好的特性,在给定视图的基础上取视图以外的元素意义不大。

切片的操作

切片的操作可以归纳为三种,分别是创建、拷贝和删除。

我们可以创建一个空的切片,它可以不是任何数组的视图,此时的切片类似于 C++ 当中的 vector:

切片的创建

var s []int // 将 s 定义为一个 slice
for i := 0; i < 100; i++ {printSlice(s)			// 打印切片的相关信息s = append(s, 2*i+1)	// 与 vector 类似, 切片的 cap(s) 同样会在需要时翻倍增长
}

可以使用内置的 make 函数创建一个指定长度(len,实际上初始的 cap 也可以指定)的空切片:

s1 := []int{2, 4, 6, 8}
printSlice(s1)s2 := make([]int, 16) // 我们希望构建一个长度为 16 的 slice
// 👆 但是目前我们还不知道 slice 当中的值, 此时需要使用内建的函数 make
s3 := make([]int, 10, 32) // 32 是 cap
printSlice(s2)            // len = 16, cap = 32
printSlice(s3)            // len = 10, cap = 32

切片的拷贝

可以使用内建的 copy 函数来完成切片的拷贝工作。‘

fmt.Println("Copying slice:")
copy(s2, s1)   // 系统内建的 copy 函数, 首先是 dst, 之后是 src
printSlice(s2) // 将 s1 的 2, 4, 6, 8 拷贝到了 s2 中

切片当中首尾元素的删除

可以使用赋值的方式来完成首尾元素的删除:

fmt.Println("Deleting elements from slice")
s2 = append(s2[:3], s2[4:]...)
printSlice(s2)fmt.Println("Popping from front")
front := s2[0]
s2 = s2[1:]fmt.Println("Popping from back")
tail := s2[len(s2)-1]
s2 = s2[:len(s2)-1]
fmt.Println(front, tail)
printSlice(s2)

上述内容的完整代码如下:

package mainimport "fmt"func printSlice(s []int) {fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s)// 可以看到 slice 的底层扩容原理与 C++ 的 vector 非常相似// 当 cap 不足时, 将 cap 翻倍
}func main() {fmt.Println("Creating Slice:")var s []int // 将 s 定义为一个 slice// 根据前面的学习内容, 我们知道 slice 是对 array 的 view// 但是现在没有 array 的定义, 或者说当前定义的 slice 没有和 array 绑定// 我推测可以直接对 slice 进行操作, 它将会自动分配一个 array// 正如前面 append 操作中所看到的, 当 array 达到 cap 时, 系统会分配新的 array// Zero value for slice is nilfor i := 0; i < 100; i++ {printSlice(s)s = append(s, 2*i+1)}s1 := []int{2, 4, 6, 8}printSlice(s1)s2 := make([]int, 16) // 我们希望构建一个长度为 16 的 slice// 👆 但是目前我们还不知道 slice 当中的值, 此时需要使用内建的函数 makes3 := make([]int, 10, 32) // 32 是 capprintSlice(s2)            // len = 16, cap = 32printSlice(s3)            // len = 10, cap = 32fmt.Println("Copying slice:")copy(s2, s1)   // 系统内建的 copy 函数, 首先是 dst, 之后是 srcprintSlice(s2) // 将 s1 的 2, 4, 6, 8 拷贝到了 s2 中fmt.Println("Deleting elements from slice")s2 = append(s2[:3], s2[4:]...)printSlice(s2)fmt.Println("Popping from front")front := s2[0]s2 = s2[1:]fmt.Println("Popping from back")tail := s2[len(s2)-1]s2 = s2[:len(s2)-1]fmt.Println(front, tail)printSlice(s2)
}
关键字:成都网页制作一般多少钱_免费项目进度管理软件_加盟教育培训哪个好_百度首页优化

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: