zoukankan      html  css  js  c++  java
  • go——数组

    数组(array)就是由若干个相同类型的元素组成的序列。

    var ipv4 [4]uint8 = [4]uint8(192,168,0,1)

    在这条赋值语句中,我们为刚声明的变量ipv4赋值。在这种情况下,变量名右边的类型字面量可以省略。
    如果它在函数里面,那么关键字var也可以省略,但赋值符号必须由=变为:=。

    类型字面量[4]uint8表明这个变量的类型长度为4且元素类型为uint的数组类型。
    注意,数组的长度是数组类型的一部分。
    只要类型声明中的数组长度不同,即两个数组类型的元素类型相同,它们也是不同的类型。
    更重要的是,一旦在声明中确定了数组类型的长度,就无法改变它了。
    同时,同一类型的数组可以使用操作符==、!=。

    package main
    
    import "fmt"
    
    var d0 [2]int //d0是数组类型的变量,因此也要遵循变量使用原则,全局变量可以只定义不使用,但是局部变量不行。
    
    func main() {
    	var d1 [3]int
    	var d2 [2]int
    	fmt.Println(d1 == d2) //invalid operation: d1 == d2 (mismatched types [3]int and [2]int)长度不同
    
    	d3 := [2]int{1, 2}
    	d4 := [2]int{2, 3}
    	fmt.Println(d3 != d4) //true
    	
    }
    

    数组初始化的方式比较灵活。
    数组类型的零值一定是一个不包含任何元素的空数组。
    一个类型的零值即为该类型变量未被显式赋值时的默认值。

    package main
    
    import "fmt"
    
    func main() {
    	var a [3]int
    
    	b := [4]int{2, 3}
    
    	c := [4]int{5, 3: 10}
    
    	d := [...]int{1, 2, 3}
    
    	e := [...]int{3, 4, 4: 9}
    
    	fmt.Println(a) //[0 0 0]      int类型的元素默认值为0
    	fmt.Println(b) //[2 3 0 0]    位提供初始化的元素自动使用默认值
    	fmt.Println(c) //[5 0 0 10]   3:10表示元素10是数组的第4个元素
    	fmt.Println(d) //[1 2 3]      省略长度,但不是没有,编译器按照初始化元素的数量确定长度
    	fmt.Println(e) //[3 4 0 0 9]
    
    }
    

    对于结构等复杂类型,可省略元素初始化类型标签。

    package main
    
    import "fmt"
    
    func main() {
    	type user struct {
    		name string
    		age  int
    	}
    
    	d := [...]user{
    		{"kebi", 26},    //省略类型标签
    		{"maoxian", 24},
    	}
    
    	fmt.Println(d)  //[{kebi 26} {maoxian 24}]
    }
    

    在定义多维数组时,仅第一维数组可以使用"..."。
    内置函数len和cap都只能返回第一维度的长度。

    package main
    
    import "fmt"
    
    func main() {
    	a := [2][3]int{
    		{1, 2, 3},
    		{4, 5},
    	}
    
    	b := [...][2]int{
    		{4, 2},
    		{3, 4},
    	}
    
    	fmt.Println(a, len(a), cap(a))
    	fmt.Println(b, len(b), cap(b))
    }
    
    /*
    [[1 2 3] [4 5 0]] 2 2
    [[4 2] [3 4]] 2 2
    */
    

    要注意区分指针数组和数组指针。
    指针数组:元素为指针类型的数组;数组指针:获取数组变量的指针。

    package main
    
    import "fmt"
    
    func main() {
    	a := [...]int{1, 2, 3}
    	fmt.Println(&a)           //数组没有指针,只有数组的元素才有指针,数组只是对底层元素的包装
    	fmt.Println(&a[0], &a[1]) //数组指针 0xc00004c0c0 0xc00004c0c8
    
    	x, y := 10, 20
    	b := [2]*int{&x, &y}  //指针数组
    	fmt.Println(b)  [0xc00004c0c0 0xc00004c0c8]
    }
    

    通过指针可以反取数据。

    package main
    
    import "fmt"
    
    func main() {
    	a := [2]int{1, 2}
    	p := &a
    	fmt.Println(*p) //[1 2]
    }
    

    Go数组是值类型,复制和传参都会复制整个数组。
    数组的指针是数组中第一个元素的指针。
    数组是内层中某个连续的片段,复制和赋值都会在此分配片段,这属于值复制,指针也不同。

    package main
    
    import "fmt"
    
    func test(x [2]int) {
    	fmt.Printf("x: %p, %v
    ", &x, x)
    }
    
    func main() {
    	a := [2]int{10, 20}
    	var b [2]int
    	b = a //复制
    
    	fmt.Printf("a: %p, %v
    ", &a, a) //a: 0xc00004e080, [10 20]
    	fmt.Printf("b: %p, %v
    ", &b, b) //b: 0xc00004e090, [10 20]
    	test(a)                          //传参//x: 0xc00004e0f0, [10 20]
    	fmt.Println(&a[0], &a[1])        //0xc00004e080 0xc00004e088
    	fmt.Println(&b[0], &b[1])        //0xc00004e090 0xc00004e098
    }
    

    如果需要,可改用指针或切片,这样就可以避免复制,以此可以减少资源的消耗。

    package main
    
    import "fmt"
    
    func test(x *[2]int) {  
    	fmt.Printf("x: %p, %v
    ", x, *x)
    }
    
    func main() {
    	a := [2]int{10, 20}
    	test(&a)  //直接传递的是指针,这样就避免复制
    
    	fmt.Printf("a: %p, %v
    ", &a, a)
    }
    
    /*
    x: 0xc00004e080, [10 20]
    a: 0xc00004e080, [10 20]
    */
    

    当需要详细规划程序所用的内存时,数组类型非常有用。
    使用数组值可以完全避免耗时费力的内存二次分配操作,因为它的长度是不可改变的。

  • 相关阅读:
    Python的优点和缺点
    如何在sed中使用变量方法及其简单
    shell脚本练习,创建数据文件注册用户并将用户信息存入文件内,用于模拟登录时使用
    shell脚本常用参数与格式
    运维方向和运维需要掌握的基本面
    linux系统awk命令精解
    数组去重方式
    原生js封装cookie获取、设置及删除
    sublime 浏览器快捷键设置
    background-image实现border效果及多图png如何实现background-size为原图一半
  • 原文地址:https://www.cnblogs.com/yangmingxianshen/p/10089961.html
Copyright © 2011-2022 走看看