【二】数组、切片、map

要清醒,理智,稳重,优秀

一、内置函数

  append :追加元素到slice里,返回修改后的slice
  close :关闭channel
  delete :从map中删除key对应的value
  panic : 用于异常处理,停止常规的goroutine
  recover :用于异常处理,允许程序定义goroutine的panic动作
  imag :返回复数(complex)的实部
  real : 返回复数(complex)的虚部
  make :用来分配内存,主要分配引用类型,返回Type本身(只能应用于slice, map, channel)
  new :分配内存,主要分配值类型,返回指向Type的指针,如int
  cap :容量,容积capacity
  copy :复制slice,返回复制的数目
  len :返回长度

二、数组与切片

概念:同一组数据类型的固定长度的序列
注意:
 长度是数组类型的一部分,因此var a[2] int和var a[3] int是不同的类型;
 数组索引是从0开始,访问超过了索引会panic;
 数组定义完成之后,每个位置会有默认值,int类型,默认值为0,string类型默认为空字符串;
数组属于值类型,当对其进行拷贝并修改副本值时,并不会改变原来的值。

1、定义方法:
// 第一种
// var <数组名称> [数组长度]<元素类型>
var arr [2]int
    arr[0] = 1
    arr[1] = 2

// 第二种
// var <数组名称> []<元素类型>
var a []int
a = make([]int,4)

// 第三种
// var <数组名称> = [数组长度]<元素类型>{元素1,元素2,...}
var arr = [2]int{1,2}
或者
arr := [2]int{1,2}

// 第四种
// var <数组名称> [数组长度]<元素类型> = [...]<元素类型>{元素1,元素2}
var arr = [...]int{1,2}
或者
arr := [...]int{1,2}

// 第五种
// var <数组名称> [数组长度]<元素类型> = [...]<元素类型>{索引1:元素1,索引2:元素2...}
var arr = [...]int{1:1,0:2}
或者
arr :=[...]int{1:1,0:2}
2、数组遍历
package main

import "fmt"

func main()  {
    var arr = [...] int {0:2,1:4,2:8}
    for i :=0;i<len(arr);i++{
        fmt.Println(arr[i])
    }
} // 结果 2,4,8

使用函数修改数组元素

package main

import "fmt"

func test(a *[3] int)  {  // 传递地址
     (*a)[0]=100
     return
}
func main()  {
    var arr [3]int
    test(&arr)  // 使用&取地址
    fmt.Println(arr[0])
} // 结果:100

斐波那契数列

package main

import "fmt"

func fab(n int)  {
    var a []int
    a = make([]int, n)

    a[0] = 1
    a[1] = 1

    for i := 2; i<n; i++{
        a[i] = a[i-1]+a[i-2]
    }
    for _,v :=range a{
        fmt.Println(v)
    }
}
func main()  {
    fab(5)
} // 结果:1,1,2,3,5
3、多维数组

多维数组相当于多添加了维数

package main

import "fmt"

func main()  {
    var a [5][4][3] int // 三维数组
    a[1][1][0] = 1
    a[1][0][0] = 1
    a[1][1][1] = 1
    fmt.Println(a)
}
/* 结果
[[[0 0 0] [0 0 0] [0 0 0] [0 0 0]] [[1 0 0] [1 1 0] [0 0 0] [0 0 0]] [[0 0 0] [0 0 0] [0 0 0] [0 0 0]] [[0 0 0] [0 0 0] [0 0 0] [0 0 0]] [[0 0 0] [0 0 0] [0 0 0] [0 0 0]]] 
*/
4、切片

概念:切片是对数组的引用,数组的长度不变,但是切片长度是可以变化的。
切片的特性和数组一样,因此遍历、长度计算等和数组一样。
切片定义和数组的定义方式在于是否有长度定义,有长度定义为数组、没有长度定义为切片

// 方式一,使用make创建
slice1 := make([]type,len,capacity) 
或者
var slice1 []type = make([]type,len,capacity)  // 其中capacity(容量)为可选参数

// 方式二,直接初始化
slice2 :=[] int {1,2}  //长度为2,容量为2

// 方式三,从数组中获取切片,与python一样
slice3 := arr[startIndex:endIndex]  //将arr数组中从下标startIndex到endIndex-1下的元素创建一个新的切片
slice4 := arr[startIndex:]  // 缺省endIndex时将表示一直到arr数组的最后一个元素
slice5 := arr[:endIndex]  //缺省startIndex时将表示从arr数组的第一个元素开始

切片操作
len:计算长度(长度是指已经被赋过值的最大下标+1)
cap:求容量(容量是指切片可容纳的最多元素个数)
copy:拷贝切片
append:向切片中追加元素

注意事项:
使用append向切片追加元素,如果长度没超过定义的切片的长度,返回原来的切片地址,如果超过了长度,切片会扩容进行重新分配地址。

package main

import "fmt"

func main()  {
    var slice2 [] int = make([] int,2,3)
    fmt.Println(len(slice2),cap(slice2))
}  // 结果2,3
package main

import "fmt"

func main()  {
    var slice1 [] int = make([] int,2,3)
    slice2 := [] int {2,2,2}
    fmt.Printf("%p--%d\n",slice1,slice2)
    slice1 = append(slice1,1)  // 追加单个元素
    fmt.Printf("slice1:%p--%d\n",slice1,slice1)
    slice3 :=append(slice1,slice2...)  // 追加另一个切片
    fmt.Printf("slice3:%p--%d\n",slice3,slice3)
    slice4 :=make([] int,len(slice3))
    copy(slice4,slice3)  // 拷贝slice3
    fmt.Printf("copy:slice3:%p--%d\n",slice3,slice3)
    fmt.Printf("slice4:%p--%d\n",slice4,slice4)
}
/* 结果
0xc00008a000--[2 2 2]
slice1:0xc00008a000--[0 0 1]
slice3:0xc000096000--[0 0 1 2 2 2]
copy:slice3:0xc000096000--[0 0 1 2 2 2]
slice4:0xc00009e000--[0 0 1 2 2 2]
*/

空(nil)切片
一个切片在未初始化之前默认为 nil,长度为 0

三、map

概念:map是go语言内置key-value的数据结构,可称为字典或关联数组。

1、map声明与初始化

map属于引用类型,声明是不会分配内存的,需要make初始化分配内存。

// 只声明不初始化,直接使用会panic,需要使用make分配内存后方可使用
var a map[keytype]valuetype
var a map[string]string
var a map[string]int
var a map[int]string
var a map[string]map[string]string

// 声明并初始化
var a map[string]string
a = make(map[string]string,8)  // 8代表容量

a := make(map[string]string,8)
a := make(map[string]string)

var a map[string]string = map[string]string{}
var a map[string]string = map[string]string{"name":"wpr","age":"22"}
2、map嵌套

map可以嵌套,类似json格式,声明时候只需要将value改为map,同样使用之前需要初始化每一层的map,示例:

package main

import "fmt"

func main()  {
    a := make(map[string]map[string]string,10)  // 两层map嵌套,声明外层map并初始化
    a["key1"] = make(map[string]string) // 初始化第二层map
    a["key1"]["key2"] = "a1"
    a["key1"]["key3"] = "b1"
    a["key1"]["key4"] = "c1"
    fmt.Println(a)
}  // 结果:map[key1:map[key2:a1 key3:b1 key4:c1]]
3、map操作

增删改查、求长度

mymap["name"] = "wpr"  // 创建或者更新
delete(mymap,"name")  // 删除
name := mymap["name"]  // 查询
len(mymap)  // 求长度
// 测试key是否存在
package main

import "fmt"
func main()  {
    a := make(map[string]string, 10)
    a["key1"] = "wpr"
    val,ok := a["key1"]  // ok为true时,代表有key
    if ok{
        fmt.Println(val)
    }else{
        fmt.Println("key1 is not exist")
    }
}  // 结果:wpr

遍历map

package main
import "fmt"

func main()  {
    a := map[string]string{"NAME":"wpr","AGE":"22"}
    for k := range a{  // 使用key进行遍历
        fmt.Println(a[k])
    }
    for k,v :=range a{  // 使用key,value进行遍历
        fmt.Println(k,v)
    }
}
/*
>>>结果:
wpr
22
AGE 22
NAME wpr
*/
4、切片嵌套map
package main
import "fmt"
func main()  {
    a := map[string]string{"NAME":"wpr","AGE":"22"}  // 初始化map
    b := make([]map[string]string,3,3)  // 初始化切片
    c := map[string]string{"NAME":"wpr","AGE":"22"} 
    b[0] = a
    fmt.Println(b)  // [map[AGE:22 NAME:wpr] map[] map[]]
    fmt.Println(c)  // map[AGE:22 NAME:wpr]
}
5、map排序

go语言中的map都是无序的,并且无内置排序方法,所有如果我们想要对map进行排序,我们需要自己实现。

方法:
 先获取所有的key,将key进行排序;
 按照排序好的key进行遍历。

package main
import (
    "fmt"
    "sort"
)
func main()  {
    a := map[string]string{"1":"a","2":"b","3":"c","4":"d"}
    var keys []string
    for k := range a{
        keys = append(keys,k)
    }
    sort.Strings(keys)  // 排序切片key
    fmt.Println(keys,len(keys))  // [1 2 3 4] 4
    for _,val := range keys{  // 循环key取值
        fmt.Println(a[val])  // a,b,c,d
    }
}
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 195,783评论 5 462
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 82,360评论 2 373
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 142,942评论 0 325
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,507评论 1 267
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,324评论 5 358
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,299评论 1 273
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,685评论 3 386
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,358评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,652评论 1 293
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,704评论 2 312
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,465评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,318评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,711评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,991评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,265评论 1 251
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,661评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,864评论 2 335

推荐阅读更多精彩内容