zoukankan      html  css  js  c++  java
  • Go 语言基础之数组

    数组定义

    Go 语言中定义数组的格式如下:

    var 数组名称 [数组长度]数组每一项数据的类型
    

    比如要定义一个长度为 3 的整数类型数组:

    var arr [3]int
    

    注意在 Go 语言中,数组的类型是由数组长度和数据类型决定的,即 [3]int[5]int 是不同的类型,另外数组长度一经定义后就不可以修改了,数组长度是一个常量

    当数组定义后而没有赋值,则会根据类型而赋默认值,比如整数或浮点数类型默认值是 0,字符串类型默认值是 '',布尔类型默认值是 false 等:

    func main() {
    	var arr1 [3]int
    	var arr2 [3]float64
    	var arr3 [3]string
    	var arr4 [3]bool
    
    	fmt.Println(arr1) // [0 0 0]
    	fmt.Println(arr2) // [0 0 0]
    	fmt.Println(arr3) // [     ]
    	fmt.Println(arr4) // [false false false]
    }
    

    如果要给数组赋值,所有值是用 {}包含,而不是一些语言中使用的 []

    func main() {
    	var arr1 [3]int
    	arr1 = [3]int{1, 2, 3}
    
    	var arr2 [3]string
    	arr2 = [3]string{"go", "java", "javascript"}
    
    	fmt.Println(arr1) // [1 2 3]
    	fmt.Println(arr2) // [go java javascript]
    }
    

    我们注意到,打印出来的数组值还是使用 [] 包含的,但是没有使用 , 隔开。如果是写 JavaScript 的前端,可能会不习惯 Go 语言中这种定义数组的方式,熟悉就好了。

    数组可以定义和赋值一起写,即:

    func main() {
    	arr1 := [3]int{1, 2, 3}
    
    	arr2 := [3]string{"go", "java", "javascript"}
    
    	fmt.Println(arr1) // [1,2,3]
    	fmt.Println(arr2) // [go java javascript]
    }
    

    这样代码更简洁。

    长度未知的数组的定义

    有时候我们要定义一个数组时,并不能预测它需要多大的长度,而且 Go 语言数组不可以修改长度,所以此时就需要一种方式能让我们定义可变长度的数组。Go 语言中提供了 ... 操作符来实现这个功能,使用如下:

    func main() {
    	arr1 := [...]int{1, 2, 3}
    
    	fmt.Println(arr1) // [1 2 3]
    	fmt.Printf("%T", arr1) // %T 表示打印值类型,数组 arr1 的类型是 [3]int
    }
    

    使用 ... 来替代具体的长度数值,就可以在赋值时自动推断出数组长度,需要注意此时数组的类型中的长度,是根据具体数组值来推断的。

    指定数组索引值初始化数组

    数组的每一项值,可以使用索引获取,索引值从 0 开始,最大索引是 len-1

    func main() {
    	arr := [3]int{3, 6, 9}
    	fmt.Print(arr[1]) // 6
    }
    

    而在数组初始化时,也可以使用索引来指定值,比如:

    func main() {
    	arr := [...]int{2, 3: 1}
    	fmt.Print(arr) // [2 0 0 1]
    }
    

    代码中数组第一项值是 2,然后指定索引为 3 的值是 1,此时会自动补全中间两位的值为 0。注意这时候的数组长度不能小于索引,如这样就是错的:

    arr := [3]int{2, 3: 1} // error: array index 3 out of bounds
    

    指定数组的长度是 3,但是索引最大也是 3,此时数组应该长度应该是 4,所以报错了。

    多维数组

    Go 语言支持多维数组,这里以二维数组为例。

    定义二维数组例子:

    func main() {
    	arr := [3][2]string{
    		{"北京", "上海"},
    		{"杭州", "南京"},
    		{"广州", "深圳"},
    	}
    
    	fmt.Println(arr) // [[北京 上海] [杭州 南京] [广州 深圳]]
    	fmt.Printf("%T", arr) // [3][2]string
    	fmt.Println(arr[1][1])  // 南京
    }
    

    其实也很好理解,[3][2]string 表示二维数组的长度是 3,数组每一项是类型为 [2]string 的一维数组。注意二维数组赋值时使用的始终是 {},我差点在里面写成 [],这是 js 写多的后果~

    有一个注意的地方就是在多维数组中,...只能用在第一层,拿上面例子来说明:

    // ... 使用在外层可以自动推断二维数组的长度
    arr := [...][2]string{
    	{"北京", "上海"},
    	{"杭州", "南京"},
    	{"广州", "深圳"},
    }
    
    // 下面这样 ... 使用在内层是错误的
    arr := [3][...]string{
    	{"北京", "上海"},
    	{"杭州", "南京"},
    	{"广州", "深圳"},
    }
    

    遍历数组

    Go 语言遍历数组,主要有两种方法,一个是用 for 循环遍历,另一个是用 range 遍历,这里简单写几个例子。

    使用 for 循环遍历:

    // 遍历一维数组
    func main() {
    	arr := [3]string{"Golang", "Java", "JavaScript"}
    
    	for i := 0; i < len(arr); i++ {
    		fmt.Println(arr[i])
    	}
    }
    
    // 输出
    Golang
    Java
    JavaScript
    
    
    // 遍历二维数组
    func main() {
    	arr := [2][3]string{
    		{"Golang", "Java", "JavaScript"},
    		{"Python", "PHP", "C"},
    	}
    
    	for i := 0; i < len(arr); i++ {
    		fmt.Println(arr[i])
    	}
    }
    
    // 输出
    [Golang Java JavaScript]
    [Python PHP C]
    

    使用 range 遍历:

    // 遍历一维数组
    func main() {
    	arr := [3]string{"Golang", "Java", "JavaScript"}
    
    	for idx, val := range arr {
    		fmt.Println(idx, val)
    	}
    }
    
    // 输出索引和值
    0 Golang
    1 Java
    2 JavaScript
    
    
    // 遍历二维数组
    func main() {
    	arr := [2][3]string{
    		{"Golang", "Java", "JavaScript"},
    		{"Python", "PHP", "C"},
    	}
    
    	for _, val := range arr {  // 当我们要忽略索引值时,可以使用 _
    		fmt.Println(val)
    	}
    }
    
    // 输出
    [Golang Java JavaScript]
    [Python PHP C]
    

    数组是值类型

    不得不说一嘴,Go 语言中的数组是值类型,这跟 js 这种动态语言中的数组很不一样,在接触 Go 语言之前,我一直坚信数组就是引用类型,但现在要习惯不同编程语言的特性。

    值类型和引用类型的代码区别就是,当修改复制出来的数据时,会不会改变原数据,如下代码证明了 Go 中的数组是值类型:

    func main() {
    	nums := [3]int{3, 5, 7}
    
    	copy_nums := nums  // 复制数组
    
    	copy_nums[0] = 4  // 修改复制数组的值
    
    	fmt.Println(nums) // [3 5 7]
    	fmt.Println(copy_nums) // [4 5 7]
    }
    

    如果数组是引用类型,那么原数组 nums 的值也应该是 [4 5 7],但是它还保持原值,所以它是值类型。

  • 相关阅读:
    Spring Security——核心类简介——获得登录用户的相关信息
    ssm配置文件
    spring boot项目下的application.properties中的logging.level设置日志级别
    spring boot项目下application.properties中使用logging.path和logging.file时的细节
    generatorConfig.xml(mybatis generator默认配置文件名)详细
    maven web项目下mybatis generator的使用
    各种xml配置文件(所含内部标签及顺序)的提示功能是真的人性化
    Git介绍、安装、命令和实战
    mac下ip地址重定向
    eclipse中Tomcat version 9.0 only supports J2EE 1.2, 1.3, 1.4, and Java EE 5, 6, 7, and 8 Web modules
  • 原文地址:https://www.cnblogs.com/wjaaron/p/14862769.html
Copyright © 2011-2022 走看看