golang数组

我傻笑你跑掉 · · 1932 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合

定义一个数组

格式: var name [n]type

n为数组长度,n>=0 且无法修改,type为数组的元素类型如:

var a [2]int

上面的例子定义了一个长度为2,元素类型为int的数组

数组长度作为数组类型的一部分,数组长度加数组元素类型才组成一个数组类型,如** [2]int** 与 ** [1]int** 不是同一个类型 所以不可以使用 == != 或进行赋值操作,

下面的程序是错误的

var a [2]int
var b [1]int
//下面的赋值是错误的
a = b

[2]int 与 [1]int 不是同一个类型

相同类型的的数组可以进行 ==与!=的比较操作

var a [2]int
var b [2]int
if a == b {
    fmt.Println("a = b")
}

a[0] = 1
if a != b {
    fmt.Println("a != b")
}

数组元素的访问与修改

数组的下标是从0开始的整数,我们可以通过下表来访问或修改相对应的元素 如:

var a = [3]string{"zhangsan","lisi","wangwu"}
fmt.Println(a[0],a[1],a[2])
a[2] = "王五"
fmt.Println(a[0],a[1],a[2])

以上程序将输出:
zhangsan lisi wangwu
zhangsan lisi 王五

数组元素的默认值

数组定义后如果没有赋值或者数组内的元素没有完全赋值,那么未赋值的元素将会由元素类型的默认值填充,关于默认值详键 类型默认值章节

下面列举几个常见类型的数组

  • var a [2]int int类型元素的默认值为0
  • var b [2]string string类型元素的默认值为空字符串
  • var c [2]float64 float类型元素的默认值为0
  • var d [2]bool boolean类型元素的默认值为false

定义数组元素的初始值

我们可以在定义数组的时候指定数组的初始值

如:var a = [2]int{1, 2}

数组可以指定下标赋值,指定下标将被赋值的指定的值,而未指定的将有默认值填充

如:c := [10]bool{0: true, 2: true, 4: true, 6: true, 8: true}

如果不指定下标 则会由下标0开始 用指定的元素初始化 没有初始化到的 将用默认值填充

如:d := [5]string{"a", "b", "c"} 将输出 [a b c 空字符串 空字符串]

自动推断数组长度

假如我有一个元素类型为string的数组,里面定义了周一到周日,那么我可以不指定数组长度而由编译器推断

如:a := [...]string{"Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"}

当然也可以用下标赋值的方式 go会自动创建一个满足条件的长度最小的数组

如:a := [...]string{2: "abc"} 将输出 [空字符串 空字符串 abc]

虽然我们可以在定义数组的时候不指定长度而由编译器推断,但不提倡这种方式

指针数组

数组元素的类型可以是任意相同的类型,所以,保存的元素为指针类型的数组就是指针数组 如:

a := [2]*int{}
x, y := 1, 2
a[0] = &x
a[1] = &y
fmt.Println(a)

a数组是一个指针数组,其中保存着变量x,y的指针

数组指针

数组指针就是指向一个数组的指针 如:

a := [5]int{1, 2, 3, 4, 5}
p := &a

数组p就是数组a的一个指针数组

获取数组的指针

使用new关键字获取数组的指针
如:a := new([2]int)
数组指针也可以对数组进行操作 方法与数组相同

数组是值类型

golang中的数组为值类型,传递进函数的时候传递的是数组的一个拷贝 看下面的一个例子

test := func(p [2]int) {
    p[0] = 123
}

a := [2]int{1, 2}
fmt.Println("传递进函数前:", a)
test(a)
fmt.Println("传递进函数后:", a)

test是一个匿名函数,关于匿名函数的概念,我们将在后边详细介绍

我们可以通过查看数组元素的地址来确定他是引用类型还是值类型

func main(){
    b := func(p [2]int) [2]int {
        fmt.Println("函数内的数组元素的地址为", &p[0], &p[1])
        return p
    }
    var a = [2]int{1, 2}
    fmt.Println("函数外的数组元素的地址为", &a[0], &a[1])
    b(a)
}

执行结果为:
函数外的数组元素的地址为 0xc82000a290 0xc82000a298
函数内的数组元素的地址为 0xc82000a2b0 0xc82000a2b8

函数内的元素地址与函数外的不相同,因为元素发生了拷贝,所以在函数内修改数组元素内容是不会影像传入函数的参数数组,因为他仅仅是外部变量的一个拷贝

数组的遍历

数组可以通过for关键字来遍历 也可以使用for range关键字来同时遍历数组的值和键

package main

import (
    "fmt"
)

func main() {
    var a = [5]string{"a", "b", "c", "d", "e"}
    for i := 0; i < len(a); i++ {
        fmt.Println(a[i])
    }
}

以上程序会依此输出 a b c d e
数组的下标是从0开始的,**len() **函数用来计算数组或切片的元素个数,我们每次输出数组中的元素,然后将数组下标+1,随后再次访问数组的下一个元素,如果这个数组长度很长, **len(a) **这个计算最好在循环外边计算好,而不是每次循环的时候去计算,这样可以提高程序的执行速度,这里为了好理解所以写在了循环里

也可以使用for配合range来遍历,把上边的程序修改一下

package main

import (
    "fmt"
)

func main() {
    var a = [5]string{"a", "b", "c", "d", "e"}
    for i, value := range a {
        fmt.Println("数组下标是", i, "对应的值为", value)
    }
}

以上程序会输出
数组下标是 0 对应的值为 a
数组下标是 1 对应的值为 b
数组下标是 2 对应的值为 c
数组下标是 3 对应的值为 d
数组下标是 4 对应的值为 e
i为数组的下标 value为下标对应的值

由于golang严格规定了定义的变量必需要使用,如果我们仅仅是想遍历数组的value而不关心索引i的时候,可以使用_(下划线)来忽略 如 for _, value := range a{}

值得一提的是,字符串实质上也是个数组,所以也可以使用len()来计算长度,使用 for range关键字来循环遍历,也可以通过下标访问

var a string = "abc"
fmt.Println(string(a[0]), a[1], a[2])

var a string = "找女友"
for k, value := range a {
    fmt.Println(k, string(value))
}

注意:utf8编码下一个汉字长度为3个字节(大部份情况下,实质上中文的长度为2-4 ) ,中文字符串遍历的时候下标一次增加3

多维数组

上面说过 数组的元素可以是golang支持的任何类型,那么,如果我的元素也是一个数组呢?

如果数组的元素也是一个数组,那么久称这个数组为多维数组 看下面这个例子

var a [2][3]int
fmt.Println(a)
a[0][1] = 222
fmt.Println(a)

a是一个长度为2,元素类型为数组的二维数组,而a的元素,是一个长度为3元素类型是int的数组

多维数组也可以初始化和使用下标来访问,例如 我给下标为1的元素 中下标为1,2的元素指定初始值:

b := [2][3]string{1: {1: "aaa", 2: "bbb"}}

访问多维数组的元素fmt.Println(b[1],b[1][1])


有疑问加站长微信联系(非本文作者)

本文来自:简书

感谢作者:我傻笑你跑掉

查看原文:golang数组

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:701969077

1932 次点击  
加入收藏 微博
下一篇:go2019
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传