Golang Slice 总结
数组
Go的切片是在数组之上的抽象数据类型,因此在了解切片之前必须要要理解数组。
数组类型由指定和长度和元素类型定义。
数组不需要显式的初始化;数组元素会自动初始化为零值:
Go的数组是值语义。一个数组变量表示整个数组,它不是指向第一个元素的指针(比如C语言的数组)。当一个数组变量被赋值或者被传递的时候,实际上会复制整个数组。(为了避免复制数组,你可以传递一个指向数组的指针,但是数组指针并不是数组。)可以将数组看作一个特殊的struct,结构的字段名对应数组的索引,同时成员的数目固定。
切片
数组虽然有适用它们的地方,但是数组不够灵活,因此在Go代码中数组使用的并不多。但是,切片则使用得相当广泛。切片基于数组构建,但是提供更强的功能和便利。
切片的类型是 []T,T 是切片元素的类型。和数组不同的是,切片没有固定的长度。
切片的字面值和数组字面值很像,不过切片没有指定元素个数:
切片可以内置函数 make 创建,函数签名为:
func make([]T, len, cap) []T
T 代表被创建的切片元素的类型。函数 make 接受一个类型、一个长度和一个可选的容量参数。调用 make 时,内部会分配一个数组,然后返回数组对应的切片。
当容量参数被忽略时,它默认为指定的长度。下面是简洁的写法:
s := make([]byte, 5)
可以使用内置函数 len 和 cap 获取切片的长度和容量信息。
len(s) == 5
cap(s) == 5
长度和容量之间的关系。
零值的切片类型变量为 nil。对于零值切片变量,len 和 cap 都将返回 0。
切片也可以基于现有的切片或数组生成。切分的范围由 大专栏 Golang Slice 总结两个由冒号分割的索引对应的半开区间指定。
切片的开始和结束的索引都是可选的;它们分别默认为零和数组的长度。
切片的本质
一个切片是一个数组切割区间的描述。它包含了指向数组的指针,切割区间的长度,和容量(切割区间的最大长度)。
切片并不复制整个切片元素。它创建一个新的切片执行同样的底层数组。这使得切片操作和数组索引一样高效。因此,通过一个新切片修改元素同样会影响到原始的切片。
切片增长不能超出其容量。增长超出切片容量将会导致运行时异常,就像切片或数组的索引超出范围引起异常一样。同样,不能使用小于零的索引去访问切片之前的元素。
切片生长(复制和追加)
要增加切片的容量必须创建一个新的、更大容量的切片,然后将原有切片的内容复制到新的切片。整个技术是一些支持动态数组语言的常见实现。
循环中复制的操作可以由 copy 内置函数替代。copy 函数将源切片的元素复制到目的切片。它返回复制元素的数目。
func copy(dst, src []T) int
copy 函数支持不同长度的切片之间的复制(它只复制最小切片长度的元素)。此外,copy 函数可以正确处理源和目的切片有重叠的情况。
但大多数程序不需要完全的控制,因此Go提供了一个内置函数 append,用于大多数场合;它的函数签名:
func append(s []T, x …T) []T
append函数将x追加到切片s的末尾,并且在必要的时候增加容量。
如果是要将一个切片追加到另一个切片尾部,需要使用…语法将第2个参数展开为参数列表。
可以声明一个零值切片(nil),然后在循环中向切片追加数据:
可能的“陷阱”
切片操作并不会复制底层的数组。此层的数组将被保存在内存中,直到它不再被引用。有时候可能会因为一个小的内存引用导致保存所有的数据。
Golang Slice 总结的更多相关文章
- golang slice 切片原理
golang 中的 slice 非常强大,让数组操作非常方便高效.在开发中不定长度表示的数组全部都是 slice .但是很多同学对 slice 的模糊认识,造成认为golang中的数组是引用类型,结果 ...
- golang slice 源码解读
本文从源码角度学习 golang slice 的创建.扩容,深拷贝的实现. 内部数据结构 slice 仅有三个字段,其中array 是保存数据的部分,len 字段为长度,cap 为容量. type s ...
- golang slice
golang 在for range一个slice时,会读出其cap长度.在for的过程中,即使动态append该slice,最终for也会在第一次读取的cap长度处停止. package main i ...
- golang slice切片的原理以及内置函数cap, len
golang中slice(切片)是常用的类型, slice是对数组进行封装 package main import ( "fmt" "strconv") fun ...
- golang——slice使用摘要
1.slice因capacity不足而重新分配的underlying array与原本的array空间是断裂的,就是说这是原本指向的空间没变,如下 arr := [...]int{1, 2, 3, 4 ...
- 【转】 golang slice array
1. array 同一类型数据的集合 var arr [n]type //声明type类型一维数组 var arr [m][n]type //声明type类型二维数组 ...
- golang:slice陷阱
slice陷阱,slice底层指向某个array,在赋值后容易导致array长期被引用而无法释放
- golang slice 使用及源码分析
1.先做个小实验 func main(){ s1:=make([]int,0,10) s1=[]int{1,2,3} ss:=make([]int,0,10) ss = s1[1:] for i:=0 ...
- golang slice分割和append copy还是引用
转载自:http://studygolang.com/articles/724 1. slice1:= slice[0:2] 引用,非复制,所以任何对slice1或slice的修改都会影响对方 dat ...
随机推荐
- 0CTF-2016-piapiapia-PHP反序列化长度变化尾部字符串逃逸
0X00 扫描一下网站目录,得到网站源码,这里说下工具使用的是dirmap,亲测御剑不好用... 0x01 审计源码: index.php <?php require_once('class.p ...
- 奔跑的绵羊js
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- 3D打印前途光明,它需要怎样的进化?
在很长一段时间内,笔者都认为3D打印只会存在于科幻场景内,众多的科技大佬在前几年也和我保持相当一致的看法,代工大王郭台铭曾口出狂言:如果3D打印能够普及,我就把"郭"字倒过来写,时 ...
- Ribbon使用及其客户端负载均衡实现原理分析
1.ribbon负载均衡测试 (1)consumer工程添加依赖 <dependency> <groupId>org.springframework.cloud</gro ...
- Python—后台运行(nohup 、&、 2>&1详解)
一.脚本文件(test.py) # -*- coding: UTF-8 -*- import time print("hello"," python") os. ...
- js 输出语句document.write()及动态改变元素中内容innerHTML的使用
操作 HTML 元素 如需从 JavaScript 访问某个 HTML 元素,您可以使用 document.getElementById(id) 方法. 请使用 "id" 属性来标 ...
- 堆排序算法以及python实现
堆满足的条件:1,是一颗完全二叉树.2,大根堆:父节点大于各个孩子节点.每个节点都满足这个道理.小根堆同理. parent = (i-1)/2 #i为当前节点 left = 2*i+1 righ ...
- 吴裕雄--天生自然 PHP开发学习:MySQL 插入多条数据
<?php $servername = "localhost"; $username = "root"; $password = "admin& ...
- webview Java与JS互调
Android调用JS:方法一 webView.loadUrl("javascript:show('"+info+"')"); Android调用JS:方法二 ...
- ssh登录脚本
#!/usr/bin/expect set timeout 100 set passwd "your password" spawn shell expect "key& ...