响应网站怎么做教学视频,wordpress+chrome+扩展,网络公司做网站后交代给客户什么,asp.net做网站吗系列文章合集
Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组
格式: var name [n]type
n为数组长度,n0 且无法修改,type为数组的元素类型如: var a [2]int上面的例子定义了一个长度为2,元素类型为int的数组… 系列文章合集
Golang - 90天从新手到大师 数组是golang中最常用的一种数据结构,数组就是同一类型数据的有序集合 定义一个数组
格式: var name [n]type
n为数组长度,n0 且无法修改,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 mainimport (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 mainimport (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 多维数组 Go 语言支持多维数组以下为常用的多维数组声明方式
var variable_name [SIZE1][SIZE2]...[SIZEN] variable_type以下实例声明了三维的整型数组
var threedim [5][10][4]int二维数组
二维数组是最简单的多维数组二维数组本质上是由一维数组组成的。二维数组定义方式如下
var arrayName [ x ][ y ] variable_typevariable_type 为 Go 语言的数据类型arrayName 为数组名二维数组可认为是一个表格x 为行y 为列下图演示了一个二维数组 a 为三行四列 二维数组中的元素可通过 a[ i ][ j ] 来访问。
初始化二维数组
多维数组可通过大括号来初始值。以下实例为一个 3 行 4 列的二维数组
a [3][4]int{ {0, 1, 2, 3} , /* 第一行索引为 0 */{4, 5, 6, 7} , /* 第二行索引为 1 */{8, 9, 10, 11} /* 第三行索引为 2 */
}访问二维数组
二维数组通过指定坐标来访问。如数组中的行索引与列索引例如
int val a[2][3]以上实例访问了二维数组 val 第三行的第四个元素。
二维数组可以使用循环嵌套来输出元素
package mainimport fmtfunc main() {/* 数组 - 5 行 2 列*/var a [5][2]int{ {0,0}, {1,2}, {2,4}, {3,6},{4,8}}var i, j int/* 输出数组元素 */for i 0; i 5; i {for j 0; j 2; j {fmt.Printf(a[%d][%d] %d\n, i,j, a[i][j] )}}
}以上实例运行输出结果为
a[0][0] 0
a[0][1] 0
a[1][0] 1
a[1][1] 2
a[2][0] 2
a[2][1] 4
a[3][0] 3
a[3][1] 6
a[4][0] 4
a[4][1] 8 数组是值类型
数组是值类型 Go中的数组是值类型而不是引用类型。这意味着当它们被分配给一个新变量时将把原始数组的副本分配给新变量。如果对新变量进行了更改则不会在原始数组中反映。
package mainimport fmtfunc main() { a : [...]string{USA, China, India, Germany, France}b : a // a copy of a is assigned to bb[0] Singaporefmt.Println(a is , a)fmt.Println(b is , b)
}
运行结果
a is [USA China India Germany France]
b is [Singapore China India Germany France]
数组的大小是类型的一部分。因此[5]int和[25]int是不同的类型。因此数组不能被调整大小。不要担心这个限制因为切片的存在是为了解决这个问题。
package mainfunc main() { a : [3]int{5, 78, 8}var b [5]intb a //not possible since [3]int and [5]int are distinct types
} Go 语言向函数传递数组 如果你想向函数传递数组参数你需要在函数定义时声明形参为数组我们可以通过以下两种方式来声明
方式一
形参设定数组大小
void myFunction(param [10]int)
{
.
.
.
}方式二
形参未设定数组大小
void myFunction(param []int)
{
.
.
.
}实例
让我们看下以下实例实例中函数接收整型数组参数另一个参数指定了数组元素的个数并返回平均值
func getAverage(arr []int, int size) float32
{var i intvar avg, sum float32 for i 0; i size; i {sum arr[i]}avg sum / sizereturn avg;
}接下来我们来调用这个函数
package mainimport fmtfunc main() {/* 数组长度为 5 */var balance []int {1000, 2, 3, 17, 50}var avg float32/* 数组作为参数传递给函数 */avg getAverage( balance, 5 ) ;/* 输出返回的平均值 */fmt.Printf( 平均值为: %f , avg );
}
func getAverage(arr []int, size int) float32 {var i,sum intvar avg float32 for i 0; i size;i {sum arr[i]}avg float32(sum / size)return avg;
}以上实例执行输出结果为
平均值为: 214.000000以上实例中我们使用的形参并为设定数组大小。