Go语言切片(Slice)

Go语言切片是对数组的抽象,Go数组的长度不可改变,在特定场景中这样的集合就不太适用,Go中提供了一种灵活,功能强悍的内置类型切片("动态数组"),与数组相比切片的长度是不固定的,可以追加元素,在追加时可能使切片的容量增大。

定义切片

你可以声明一个未指定大小的数组来定义切片:

var identifier []type

切片不需要说明长度,或使用make()函数来创建切片:

var slice1 []type = make([]type, len)
// 也可以简写为
slice1 := make([]type, len)

也可以指定容量,其中capacity未可选参数:

make([]T, length, capacity)

这里len是数组的长度并且也是切片的初始长度。

切片初始化

s := [] int {1, 2, 3}

直接初始化切片,[]表示是切片类型,{1, 2, 3}初始化值依次是1, 2, 3.其cap=len=3

s := arr[:]

初始化切片s,是数组arr的引用。

s := arr[startIndex:endIndex]

将arr中从下标startIndex到endIndex-1下的元素创建为一个新的切片。

s := arr[startIndex:]

缺省endIndex时将表示一直到arr的最后一个元素。

s1 := s[startIndex:endIndex]

通过切片s初始化切片s1.

s := make([]int, len, cap)

通过内置函数make()初始化切片s,[]int标识为其元素类型为int的切片。

len()和cap()函数

切片是可索引的,并且可以有len()方法获取长度,切片提供了计算容量的方法cap()可以测量切片最长可以达到多少,以下为具体实例:

package main

import "fmt"

func main() {
var numbers = make([]int,3,5) printSlice(numbers)
} func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上实例运行输出结果为:

len = 3 cap = 5 slice = [0 0 0]

空(nil)切片

一个切片在未初始化之前默认为nil,长度为0,实例如下:

package main

import "fmt"

func main() {
var numbers []int printSlice(numbers) if(numbers == nil){
fmt.Printf("切片是空的")
}
} func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上实例运行输出结果为:

len=0 cap=0 slice=[]
切片是空的

切片截取

可以通过设置下限及上限来设置截取切片[lower-bound:upper-bound],实例如下:

package main

import "fmt"

func main() {
/* 创建切片 */
numbers := []int{0,1,2,3,4,5,6,7,8}
printSlice(numbers) /* 打印原始切片 */
fmt.Println("numbers ==", numbers) /* 打印子切片从索引1(包含) 到索引4(不包含)*/
fmt.Println("numbers[1:4] ==", numbers[1:4]) /* 默认下限为 0*/
fmt.Println("numbers[:3] ==", numbers[:3]) /* 默认上限为 len(s)*/
fmt.Println("numbers[4:] ==", numbers[4:]) numbers1 := make([]int,0,5)
printSlice(numbers1) /* 打印子切片从索引 0(包含) 到索引 2(不包含) */
number2 := numbers[:2]
printSlice(number2) /* 打印子切片从索引 2(包含) 到索引 5(不包含) */
number3 := numbers[2:5]
printSlice(number3) } func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上代码运行输出结果为:

len=9 cap=9 slice=[0 1 2 3 4 5 6 7 8]
numbers == [0 1 2 3 4 5 6 7 8]
numbers[1:4] == [1 2 3]
numbers[:3] == [0 1 2]
numbers[4:] == [4 5 6 7 8]
len=0 cap=5 slice=[]
len=2 cap=9 slice=[0 1]
len=3 cap=7 slice=[2 3 4]

append()和copy()函数

如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来,下面的代码描述了从拷贝切片的copy方法和向切片追加新元素的append方法:

package main

import "fmt"

func main() {
var numbers []int
printSlice(numbers) /* 允许追加空切片 */
numbers = append(numbers, 0)
printSlice(numbers) /* 向切片添加一个元素 */
numbers = append(numbers, 1)
printSlice(numbers) /* 同时添加多个元素 */
numbers = append(numbers, 2,3,4)
printSlice(numbers) /* 创建切片 numbers1 是之前切片的两倍容量*/
numbers1 := make([]int, len(numbers), (cap(numbers))*2) /* 拷贝 numbers 的内容到 numbers1 */
copy(numbers1,numbers)
printSlice(numbers1)
} func printSlice(x []int){
fmt.Printf("len=%d cap=%d slice=%v\n",len(x),cap(x),x)
}

以上代码运行输出结果为:

len=0 cap=0 slice=[]
len=1 cap=1 slice=[0]
len=2 cap=2 slice=[0 1]
len=5 cap=6 slice=[0 1 2 3 4]
len=5 cap=12 slice=[0 1 2 3 4]

Go语言范围(Range)

Go语言中range关键字用于for循环中迭代数组(array)、切片(slice)、通道(channel)或集合(map)的元素,在数组和切片中它返回元素的索引值,在集合中返回key-value对的key值,如下实例:

package main
import "fmt"
func main() {
//这是我们使用range去求一个slice的和。使用数组跟这个很类似
nums := []int{2, 3, 4}
sum := 0
for _, num := range nums {
sum += num
}
fmt.Println("sum:", sum)
//在数组上使用range将传入index和值两个变量。上面那个例子我们不需要使用该元素的序号,所以我们使用空白符"_"省略了。有时侯我们确实需要知道它的索引。
for i, num := range nums {
if num == 3 {
fmt.Println("index:", i)
}
}
//range也可以用在map的键值对上。
kvs := map[string]string{"a": "apple", "b": "banana"}
for k, v := range kvs {
fmt.Printf("%s -> %s\n", k, v)
}
//range也可以用来枚举Unicode字符串。第一个参数是字符的索引,第二个是字符(Unicode的值)本身。
for i, c := range "go" {
fmt.Println(i, c)
}
}

以上实例运行输出结果为:

sum: 9
index: 1
a -> apple
b -> banana
0 103
1 111

Go语言集合(Map)

Map是一种无序的键值对的集合,Map最重要的一点是通过key来快速检索数据,key类似于索引,指向数据的值。Map是一种集合,所以我们可以像迭代数组和切片那样迭代它。不过Map是无序的,我们无法决定它的返回顺序,这是因为Map是使用hash表来实现的。

定义Map

可以是用内建函数make也可以使用map关键字来定义Map:

/* 声明变量,默认 map 是 nil */
var map_variable map[key_data_type]value_data_type /* 使用 make 函数 */
map_variable := make(map[key_data_type]value_data_type)

如果不初始化map,那么就会创建一个nil map。nil map不能用来存放键值对。

实例

下面实例演示了创建和使用map:

package main

import "fmt"

func main() {
var countryCapitalMap map[string]string
/* 创建集合 */
countryCapitalMap = make(map[string]string) /* map 插入 key-value 对,各个国家对应的首都 */
countryCapitalMap["France"] = "Paris"
countryCapitalMap["Italy"] = "Rome"
countryCapitalMap["Japan"] = "Tokyo"
countryCapitalMap["India"] = "New Delhi" /* 使用 key 输出 map 值 */
for country := range countryCapitalMap {
fmt.Println("Capital of",country,"is",countryCapitalMap[country])
} /* 查看元素在集合中是否存在 */
captial, ok := countryCapitalMap["United States"]
/* 如果 ok 是 true, 则存在,否则不存在 */
if(ok){
fmt.Println("Capital of United States is", captial)
}else {
fmt.Println("Capital of United States is not present")
}
}

以上实例运行结果为:

Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Capital of United States is not present

delete()函数

delete()函数用于删除集合的元素,参数为map和其对应的key。实例如下:

package main

import "fmt"

func main() {
/* 创建 map */
countryCapitalMap := map[string] string {"France":"Paris","Italy":"Rome","Japan":"Tokyo","India":"New Delhi"} fmt.Println("原始 map") /* 打印 map */
for country := range countryCapitalMap {
fmt.Println("Capital of",country,"is",countryCapitalMap[country])
} /* 删除元素 */
delete(countryCapitalMap,"France");
fmt.Println("Entry for France is deleted") fmt.Println("删除元素后 map") /* 打印 map */
for country := range countryCapitalMap {
fmt.Println("Capital of",country,"is",countryCapitalMap[country])
}
}

以上实例运行结果为:

原始 map
Capital of France is Paris
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi
Entry for France is deleted
删除元素后 map
Capital of Italy is Rome
Capital of Japan is Tokyo
Capital of India is New Delhi

Go语言【第十二篇】:Go数据结构之:切片(Slice)、范围(Range)、集合(Map)的更多相关文章

  1. Python开发【第二十二篇】:Web框架之Django【进阶】

    Python开发[第二十二篇]:Web框架之Django[进阶]   猛击这里:http://www.cnblogs.com/wupeiqi/articles/5246483.html 博客园 首页 ...

  2. 解剖SQLSERVER 第十二篇 OrcaMDF 行压缩支持(译)

    解剖SQLSERVER 第十二篇   OrcaMDF 行压缩支持(译) http://improve.dk/orcamdf-row-compression-support/ 在这两个月的断断续续的开发 ...

  3. 第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  4. 第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  5. Python之路【第十二篇】:JavaScrpt -暂无内容-待更新

    Python之路[第十二篇]:JavaScrpt -暂无内容-待更新

  6. C语言第十二讲,文件操作.

    C语言第十二讲,文件操作. 一丶文件操作概述 在操作系统中,我们的文档都称为文件.操作系统也为我们提供了接口进行操作.不同语言都是使用的相同的接口,只不过封装的上层接口不一样 操作文件的步骤 打开文件 ...

  7. 【译】第十二篇 Integration Services:高级日志记录

    本篇文章是Integration Services系列的第十二篇,详细内容请参考原文. 简介在前一篇文章我们配置了SSIS内置日志记录,演示了简单和高级日志配置,保存并查看日志配置,生成自定义日志消息 ...

  8. 【译】第十二篇 SQL Server代理多服务器管理

    本篇文章是SQL Server代理系列的第十二篇,详细内容请参考原文 在这一系列的上一篇,我们查看了维护计划,一个维护计划可能会创建多个作业,多个计划.你还简单地看了SSIS子系统,并查看了维护计划作 ...

  9. 跟我学SpringCloud | 第十二篇:Spring Cloud Gateway初探

    SpringCloud系列教程 | 第十二篇:Spring Cloud Gateway初探 Springboot: 2.1.6.RELEASE SpringCloud: Greenwich.SR1 如 ...

  10. Egret入门学习日记 --- 第十二篇(书中 5.1节 内容)

    第十二篇(书中 5.1节 内容) 昨天把 第4章完成了. 今天来看第5章. 接下来是 5.1节 的内容. 总结一下 5.1节 的重点: 1.如何制作一个公用按钮皮肤. 跟着做: 重点1:如何制作一个公 ...

随机推荐

  1. 20145207 myeclipse测试

    实验博客  

  2. 【原创】Odoo开发文档学习之:构建接口扩展(Building Interface Extensions)(边Google翻译边学习)

    构建接口扩展(Building Interface Extensions) 本指南是关于为Odoo的web客户创建模块. 要创建有Odoo的网站,请参见建立网站;要添加业务功能或扩展Odoo的现有业务 ...

  3. P1563 玩具谜题

    P1563 玩具谜题 题目描述 小南有一套可爱的玩具小人, 它们各有不同的职业. 有一天, 这些玩具小人把小南的眼镜藏了起来. 小南发现玩具小人们围成了一个圈,它们有的面朝圈内,有的面朝圈外.如下图: ...

  4. 鸡啄米:C++编程之十三学习之类与对象,类的声明,成员的访问控制

    1. 本次学习鸡啄米课程第13篇,把比较重要的学习记录下来,以敦促自己更好的学习.推荐他们的网址学习:http://www.jizhuomi.com/school/c/97.html 2. 在面向过程 ...

  5. MVC下的Area区域知识点

    新建area区域 1.如果与根目录下的url相同,那么需要在RouteConfig.cs中 public static void RegisterRoutes(RouteCollection rout ...

  6. android分析windowManager、window、viewGroup之间关系(一)

    本文将主要介绍addview方法,在windowManager.window.viewGroup中的实现原理.首先将介绍这些类结构关系,然后分析其内在联系,介绍实现原理,最后介绍重要的一个参数wind ...

  7. Use GitHub Desktop to get GitHub projects

    Find the project's https git file in the home page of the project. e.g. https://github.com/PrismLibr ...

  8. Python拼接字符串的7种方法

    1.直接通过+操作: s = 'Python'+','+'你好'+'!'print(s) 打印结果: Python,你好! 2.通过join()方法拼接: 将列表转换成字符串 strlist=['Py ...

  9. Unity OBB分包(基础APK+OBB) 与apk签名

    1.OBB (Opaque Binary Blob)文件格式,是安卓游戏通用数据包.在一些大型游戏上较为常见,同时还附以Data文件,亦或是md5.dat文件出现 产生原因:由于某些平台对于apk上传 ...

  10. 为什么Python在列表和元组的末尾允许使用逗号?

    Python 允许您在列表,元组和字典的末尾添加一个尾随逗号: [1, 2, 3,] ('a', 'b', 'c',) d = { "A": [1, 5], "B&quo ...