定义数组

var arr1 [5]int   //整型类型
fmt.Println(arr1) //[0 0 0 0 0]
//赋值
arr1 = [5]int{1, 2, 3, 4, 5}
fmt.Println(arr1) //[1 2 3 4 5] var arr2 [6]*int //整型指针数组
fmt.Println(arr2) //[<nil> <nil> <nil> <nil> <nil> <nil>] var arr3 [2][3]int //二维数组
fmt.Println(arr3) //[[0 0 0] [0 0 0]] // 使用简短的格式
arr4 := [5]int{2, 4, 6, 8, 10}
fmt.Println(arr4) //[2 4 6 8 10] //其他方式,如果长度的位置是... 表示数组长度是根据后面的数据元素个数来计算
arr5 := [...]int{2, 3, 4, 5, 6, 7}
fmt.Println(arr5, len(arr5)) //[2 3 4 5 6 7] 6 // 指定数组的索引来赋值
arr6 := [...]int{5: 10, 7: 23}
//将数组下标为5的元素赋值为10,将数组下标为7的元素赋值为23
//数组长度为8
fmt.Println(arr6, len(arr6)) //[0 0 0 0 0 10 0 23] 8 arr7 := [2][3]int{{1, 2, 3}, {4, 5, 6}}
fmt.Println(arr7) //[[1 2 3] [4 5 6]]

  

数组访问与数组长度

arr1 := [5]int{2, 4, 6, 8, 10}
fmt.Println(arr1) // [2 4 6 8 10]
fmt.Println("length:", len(arr1)) //length: 5
// arr1[5] = 100 //出错,数组越界
arr1[0] = 99
fmt.Println(arr1) //[99 4 6 8 10] arr2 := [2][3]int{{1, 2, 3}, {4, 5, 6}}
fmt.Println(len(arr2)) //2
fmt.Println(len(arr2[0])) //3
fmt.Println(arr2[1][1]) //5

  

数组遍历

arr1 := [5]int{2, 4, 6, 8, 10}
for i := 0; i < len(arr1); i++ {
fmt.Println(arr1[i]) //2 4 6 8 10
}
for i, v := range arr1 {
fmt.Print(i, "=>", v) // 0=>2,1=>4,2=>6,3=>8,4=>10
}
// 不需要索引的时候,可以将用_代替i
for _, v := range arr1 {
fmt.Println(v) //2,4,6,8,10
}

  

数组作为函数参数

  数组作为函数作为参数时,如果是给形参传递数组名,那么就是传值操作,传递的是数组的副本,修改副本的内容,并不会影响实参。

  要想在函数中对数组的修改作用到实参,可以用数组指针,即->使用指针的形式,将数组的地址传递给函数,并且函数定义时,接收一个指针类型的参数,那么就可以对数组内部进行修改,但是不能修修改数组长度。

package main

import "fmt"

func Double(arr [5]int) [5]int {
for i := 0; i < 5; i++ {
arr[i] *= 2
}
return arr
} //接收的指针类型,即数组的地址
//注意这里的形参要写成 arr *[5]int 不要写成arr [5]*int
//arr [5]*int表示的是有五个元素的数组,每个元素是一个指针,即5个指针
//arr *[5]int表示的是一个指针,这一个指针指向一个拥有5个元素的数组,每个元素时一个int型变量
func Triple(arr *[5]int) {
for i := 0; i < 5; i++ {
arr[i] *= 3
}
}
func main() {
var arr2 [6]*int //整型指针数组
fmt.Println(arr2) //[<nil> <nil> <nil> <nil> <nil> <nil>]
arr := [5]int{1, 2, 3, 4, 5}
fmt.Println(arr) //[1 2 3 4 5] arr1 := Double(arr)
fmt.Println(arr1) //[2 4 6 8 10]
fmt.Println(arr) //[1 2 3 4 5] Triple(&arr)
fmt.Println(arr) //[3 6 9 12 15]
}

  

数组类型、数组比较

  数组的长度一旦确定,就不能再改变。如果要改变,只能转换为slice,但是用了slice之后,改变的是slice的长度,但是数组长度始终不变。

  数组长度不同,那么数组就不是同一个类型,不能相互赋值-->参数传递。

  相同类型的数组可以进行比较,这里的类型不只是数组元素的类型,也包括数组的长度都要相同,才能进行比较。

package main
import "fmt"
func Double(arr [5]int) [5]int {
for i := 0; i < 5; i++ {
arr[i] *= 2
}
return arr
} func main() {
arr1 := [5]int{1, 2, 3, 4, 5}
Double(arr1) //正确 形参和实参都是[5]int类型,注意[5]int是一个类型 arr2 := [6]int{1, 2, 3, 4, 5, 6}
Double(arr2) //错误,不能将类型为[6]int的实参,赋值给类型为[5]int的形参
//[5]int和[6]int是两个不同的类型
}

  

  

创建切片

var slice []int
//定义一个空切片,注意上面[]中没有指定长度,如果指定长度,就代表是数组了
fmt.Println(slice) //[] slice1 := []int{1, 2, 3, 4, 5}
//创建一个长度和容量为5的切片
fmt.Println(slice1) //[1 2 3 4 5]
fmt.Println(len(slice1), cap(slice1)) //5 5 slice2 := []int{5: 10}
//创建一个长度和容量为6的切片
fmt.Println(slice2) //[0 0 0 0 0 10]
fmt.Println(len(slice2), cap(slice2)) //6 6 //使用make创建切边
//make(type,len,cap),未指定cap是,cap和len相等
slice3 := make([]int, 5, 10)
fmt.Println(slice3, len(slice3), cap(slice3)) //[0 0 0 0 0] 5 10
slice4 := make([]int, 6)
fmt.Println(slice4, len(slice4), cap(slice4)) //[0 0 0 0 0 0] 6 6 // 利用数组创建切片
//[strat:end]左闭右开,start省略时,默认为0;end省略时默认为数组或者切片长度
arr := [10]int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
slice5 := arr[3:]
fmt.Println(slice5) //[3 4 5 6 7 8 9] slice6 := arr[:7]
fmt.Println(slice6) //[0 1 2 3 4 5 6] slice7 := arr[4:8]
fmt.Println(slice7) //[4 5 6 7] slice8 := arr[:]
fmt.Println(slice8) //[0 1 2 3 4 5 6 7 8 9]

  通过len函数求的切片长度,判断是否为空。

append函数

  使用append函数后,返回的是一个slice类型,不是数组类型

slice := []int{1, 2, 3, 4, 5}
fmt.Println(slice) //[1 2 3 4 5] //追加元素
slice = append(slice, 6)
fmt.Println(slice) //[1 2 3 4 5 6] //追加切片
s1 := []int{99, 100}
//注意下面的...表示解构,即,将切片的内容展开后填充到该位置
slice = append(slice, s1...)
fmt.Println(slice)

  不能对数组调用append函数,即,append函数的第一个参数必须是slice。

copy函数

  copy(destination,resource),复制之后,dest的长度并不会改变,即使复制给他的切片长度远大于它。

//长的slice复制到短的slice
s1 := []int{1, 2, 3, 4, 5}
s2 := []int{10, 20, 30, 40}
copy(s2, s1)
fmt.Println(s2) //[1 2 3 4] //短的slice复制到长的slice
s3 := []int{2, 3, 4}
s4 := []int{9, 8, 7, 6, 5}
copy(s4, s3)
fmt.Println(s4) //[2 3 4 6 5] //相同长度的slice进行复制
s5 := []int{1, 2, 3}
s6 := []int{4, 5, 6}
copy(s6, s5)
fmt.Println(s6) //[1 2 3]

  不能使用copy进行数组的复制操作,即,copy的两个参数都必须是slice。

slice作为函数参数

  将数组传递给函数之后,在函数中操作的是数组的副本。虽然可以使用数组指针形式传递,但是更通用的是使用slice,使用slice之后,可以通过在函数中修改slice,来达到修改数组的目的。

package main

import "fmt"

//参数是数组类型
func Double(arr [5]int) {
for i := 0; i < 5; i++ {
arr[i] *= 2
}
} //类型是slice类型
func Triple(slice []int) {
for i := 0; i < len(slice); i++ {
slice[i] *= 3
}
}
func main() {
arr := [5]int{1, 2, 3, 4, 5}
Double(arr)
fmt.Println(arr) //[1 2 3 4 5] //数组转换为切片
slice := arr[:]
Triple(slice)
fmt.Println(arr) //[3 6 9 12 15]
}

  

创建map

//定义空的映射,默认值为nil
var m1 map[int]string
fmt.Println(m1) //map[]
//再进行初始化
m1 = map[int]string{
1: "hello",
8: "world", //注意这种写法,末尾的逗号不可省
}
fmt.Println(m1) //map[1:hello 8:world] //使用make创建映射,注意此时最多只用两个参数,
//一个是map的映射类型,一个map的容量,容量可以省略
//但是没有len这一个参数,即不能指定长度这一项
m2 := make(map[int]string, 100)
fmt.Println(m2, len(m2)) m3 := make(map[string][]string)
m3["server"] = []string{"apache", "nginx"}
m3["language"] = []string{"php", "golang", "python"}
fmt.Println(m3) //map[server:[apache nginx] language:[php golang python]] //创建映射,同时初始化,此时不需要使用make
m4 := map[int]string{1: "demo", 2: "test"}
fmt.Println(m4) //map[1:demo 2:test]

  

删除map元素

//字符串映射到string类型的切片
m1 := map[string][]string{
"server": []string{"apache", "nginx"},
"language": []string{"php", "python", "golang"},
}
fmt.Println(m1) //map[server:[apache nginx] language:[php python golang]] //删除没有的key,不报错
delete(m1, "client")
fmt.Println(m1) //map[server:[apache nginx] language:[php python golang]] delete(m1, "server")
fmt.Println(m1) //map[language:[php python golang]]

  

查找map元素

//字符串映射到string类型的切片
m1 := map[string][]string{
"server": []string{"apache", "nginx"},
"language": []string{"php", "python", "golang"},
}
fmt.Println(m1) //map[server:[apache nginx] language:[php python golang]] //访问一个不存在的元素,不会报错,返回类型零值
fmt.Println(m1["client"]) //[] v, exists := m1["client"]
fmt.Println(v, exists) //[] false v, exists = m1["server"]
fmt.Println(v, exists) //[apache nginx] true

  

遍历map

//字符串映射到string类型的切片
m1 := map[string][]string{
"server": []string{"apache", "nginx"},
"language": []string{"php", "python", "golang"},
}
for key, value := range m1 {
fmt.Println(key, "=>", value)
}
//server => [apache nginx]
//language => [php python golang]

  映射是无序的,所以遍历多次的结果,元素的顺序不一定完全相同

map注意事项

  1、map之间不能进行比较,但是可以和nil进行比较

  2、不能对map取地址,因为map本就是引用类型

var m0 map[int]string
fmt.Println(m0 == nil) //true var m1 map[int]string
fmt.Println(m0 == m1) //不能进行比较,会报错 m2 := map[int]string{1: "one", 2: "two"}
fmt.Println(m2 == nil) //false

  

map作为函数参数

package main

import "fmt"

//接受一个map
func Show(m map[int]string) {
m[1] = "three"
m[3] = "four"
}
func main() {
m1 := map[int]string{
1: "one",
2: "two",
}
fmt.Println(m1) //map[1:one 2:two] Show(m1)
fmt.Println(m1) //map[3:four 1:three 2:two]
}

  将map作为函数的参数,在函数中修改map,会直接影响到实参,因为map是引用类型。

  

Golang 数组、切片、映射的更多相关文章

  1. Golang 数组 切片 字典 基本知识点

    数组 数组的声明 var arrayName [arraySize]dataType eg: var array1 [5]int 在声明数组时,必须指定数组名,数组长度和数组元素的类型. 数组的初始化 ...

  2. GoLang数组切片

    1. 数组1.1 如何定义数组同java数组一样,数组是一组内存连续且类型相同的数据组成 //不初始化初始值默认为0 var arr1 = [5]int{} var arr2 = [5]int{1,2 ...

  3. [golang note] 数组切片

    数组 √ golang数组包含的每个数据称为数组元素(element),数组包含的元素个数被称为数组长度(length). √ golang数组的长度在定义后不可更改,并且在声明时可以是一个常量或常量 ...

  4. golang中不定参数与数组切片的区别

    package main import "fmt" func main() { myfunc1(, , , ) //传递不定数量的参数 myfunc2([], , , }) //传 ...

  5. Go语言学习之4 递归&闭包&数组切片&map&锁

    主要内容: 1. 内置函数.递归函数.闭包2. 数组与切片3. map数据结构4. package介绍 5. 排序相关 1. 内置函数.递归函数.闭包 1)内置函数 (1). close:主要用来关闭 ...

  6. 窥探Swift之数组安全索引与数组切片

    今天是元宵节,祝大家元宵节快乐!在Swift中的数组和字典中下标是非常常见的,数组可以通过索引下标进行元素的查询,字典可以通过键下标来获取相应的值.在使用数组时,一个常见的致命错误就是数组越界.如果在 ...

  7. go语言 类型:数组切片

    初看起来,数组切片就像一个指向数组的指针,实际上它拥有自己的数据结构,而不仅仅是个指针.数组切片的数据结构可以抽象为以下3个变量: 1.一个指向原生数组的指针: 2.数组切片中的元素个数: 3.数组切 ...

  8. go语言中的数组切片:特立独行的可变数组

    go语言中的数组切片:特立独行的可变数组 初看go语言中的slice,觉得是可变数组的一种很不错的实现,直接在语言语法的层面支持,操作方面比起java中的ArrayList方便了许多.但是在使用了一段 ...

  9. GO中的数组切片

    GO中的数组切片可以看做是功能更强大的数组,在append数据时,可以自动调整内存大小以适应数据实际大小,有些类似于C#中的List<T>. GO 中数组切片的“容量”与实际储存的大小可以 ...

随机推荐

  1. hashCode相关性能优化

    学习下hashMap中用到的关于hashCode性能优化技巧.作为笔记.为之后并发深入作基础. 1.关于提高性能的hash算法 在被模的位数为2的n次方时,用位与取代效率低下的模运算.位与效率相比模运 ...

  2. ffmpeg m3u8 转 MP4

    ffmpeg -i 你的m3u8地址 -acodec copy -vcodec copy -f mp4 output.mp4

  3. ubuntu16.04安装配置nagios

    参考博文:https://www.howtoing.com/ubuntu-nagios/ 该博文真实有效可供参考,按照步骤,基本可以成功 一.安装的先决条件 sudo apt-get install ...

  4. AI 概率论

    概率论 不确定性 量化 频率 频率派 贝叶斯派 1.随机变量(random variable) 随机取不同值的变量,取值可以离散或者连续. 2.概率分布(probability distributio ...

  5. PHPStorm FTP upload could not change to work directory 无法更改目录

    使用PHPStorm 2016 2.2版本 设置代码及时上传的时候遇到了这个问题,无法上传代码. 配置好了FTP之后去测试,是正常的,如下图一所示,也开启了那个被动模式(见图二),但是去上传代码的时候 ...

  6. 方差(variance)、标准差(Standard Deviation)、均方差、均方根值(RMS)、均方误差(MSE)、均方根误差(RMSE)

    方差(variance).标准差(Standard Deviation).均方差.均方根值(RMS).均方误差(MSE).均方根误差(RMSE) 2017年10月08日 11:18:54 cqfdcw ...

  7. Yarn 入门

    Yarn 是快速.可靠.安全的 js 包管理器. 关键词: nodejs, 包管理, yarn 简介 Yarn 是快速.可靠.安全的 js 包管理器. 快速 - Yarn 会缓存它下载的每个包,所以无 ...

  8. Struts学习总结-02 上传文件

    Struts 2框架提供了内置支持处理文件上传使用基于HTML表单的文件上传.上传一个文件时,它通常会被存储在一个临时目录中,他们应该由Action类进行处理或移动到一个永久的目录,以确保数据不丢失. ...

  9. C#去除字符串中的反斜杠

    如下,可以使用C#的Replace()方法来替换,但有一点需要注意的是backslash(反斜杠)是特殊字符. string s = "[\"aaaaaaaaaaaaaaaaaaa ...

  10. Cordova套网站

    用Cordova套网站,只修改Content的话,打包后的App,在点击后会打开浏览器,并没有在App中显示内容. 需要设置allow-navigation为 * <?xml version=' ...