zoukankan      html  css  js  c++  java
  • Go 其二 数组与切片

    艺多不压身,学习一下最近蛮火的Go语言,整理一下笔记。相关Code和笔记也放到了Git上,传送门

    数组的声明
    var a [3] int //声明并初始化为默认零值
    a[0] = 1

    b := [3]int{1,2,3} //声明同时初始化
    c := [2][2]int{{1,2},{3,4}} //多维数组初始化

    Go语言中定义的变量一定要使用,否则会报错,但如果只是想使用foreach的写法,可以使用 _ 来占位.

    //foreach的写法, idx即为数组的索引的值
    for idx, e:= range arr2 {
    t.Log(idx, e)
    }

    //Go语言中定义的变量一定要使用,所以下面的写法会报错 idx declared but not used
    // for idx, e:= range arr2 {
    // t.Log(e)
    // }

    //如果只是想使用foreach的写法,可以使用 _ 来占位
    for _, e:= range arr2 {
    t.Log(e)
    }

    数组截取
    a[开始索引(包含), 结束索引(不包含)]
    a := [...] int {1,2,3,4,5}
    a[1:2] // 2
    a[1:3] // 2,3
    a[1:len(1)] // 2, 3, 4, 5
    a[1:] //2, 3, 4, 5 //从索引1开始一直到末尾
    a[:3] //1,2,3 //从索引0开始,一直到索引为3的位置,不包含索引为3的值


    ---------------------------------------------------------------

    切片

    切片在别的语言中不一定有,比如c#

    使用起来像是可变长数组

    切片内部结构
    实际上是一个结构体,包含三个元素
    1.指针,指向一片连续的存储空间(一个数组)ptr
    2.切片内的元素个数 len
    3.指针指向的这个数组的长度,容量 cap

    //与声明数组很类似,区别是没有指定长度!例如
    var s0 []int
    利用len()方法来获得切片内元素个数
    利用cap()方法来获得切片空间大小
    利用append(s0, 1)来填充切片

    使用make方法来声明长度和容量不同的切片 例如
    //这里s2长度为3,但容量为5
    s2 := make([]int, 3, 5)
    其中len个元素会被初始化为默认值0,未初始化元素不可访问

    切片本质上是共享的存储结构,注意这里的共享指的是由同一个切片“派生”出的其他切片或数组,例如
    year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
    q2 := year[3:6]
    summer := year[5:8]
    year,q2,summer是共享存储空间的

    而反之,如
    a := []int{1,2,3,4}
    b := []int{1,2,3,4}
    虽然初始的值相同,但其实是不共享存储空间的

    ---------------------------------------------------------------

    数组 VS 切片
    1. 容量是否可以伸缩,数组不可以,切片可以
    2. 是否可以进行比较,数组可以与数组比较,切片与切片之间不可以比较

    附录:

    数组相关Code:

    package array_test
    
    import "testing"
    
    func TestArrayInit(t *testing.T){
    	var arr [3]int
    	t.Log(arr[1],arr[2])
    
    	arr1 := [4]int{1,2,3,4}
    	//不指定长度且初始化时可以用[...]
    	arr2 := [...]int{1,2,3,4,5}
    	arr1[1] = 9
    	t.Log(arr1[1], arr1[3])
    	t.Log(arr2[2])
    }
    
    func TestArrayTraval(t *testing.T){
    	arr2 := [...]int{1,2,3,4,5}
    	for i:= 0; i < len(arr2); i++{
    		t.Log(arr2[i])
    	}
    
    	//foreach的写法, idx即为数组的索引的值
    	for idx, e:= range arr2 {
    		t.Log(idx, e)
    	}
    
    	//Go语言中定义的变量一定要使用,所以下面的写法会报错 idx declared but not used
    	// for idx, e:= range arr2 {
    	// 	t.Log(e)
    	// }
    
    	//如果只是想使用foreach的写法,可以使用 _ 来占位
    	for _, e:= range arr2 {
    		t.Log(e)
    	}
    }
    
    func TestArraySection(t *testing.T){
    	arr3 := [...] int{1,2,3,4,5}
    	arr3_sec := arr3[:3]
    	t.Log(arr3_sec)
    
    	arr3_sec2 := arr3[3:]
    	t.Log(arr3_sec2)
    }
    

      

    切片相关code:

    package slice_test
    
    import "testing"
    
    func TestSliceInit(t *testing.T){
    	//与声明数组很类似,区别是没有指定长度!
    	var s0 []int
    	t.Log(len(s0), cap(s0))
    	s0 = append(s0, 1)
    	t.Log(len(s0), cap(s0))
    
    	//初始化
    	s1 := []int{1,2,3,4}
    	t.Log(len(s1), cap(s1))
    
    	//这里s2长度为3,但容量为5
    	s2 := make([]int, 3, 5)
    	t.Log(len(s2), cap(s2))
    	//这里会报错,因为后两个元素会越界
    	//t.Log(s2[0],s2[1],s2[2],s2[3],s2[4])
    	t.Log(s2[0],s2[1],s2[2])
    	s2 = append(s2, 1)
    	t.Log(s2[0],s2[1],s2[2],s2[3])
    }
    
    func TestSliceGrowing(t *testing.T){
    	s:=[]int{}
    	for i:=0; i<10; i++{
    		s = append(s, i)
    		t.Log(len(s), cap(s))
    	}
    
    	//输出结果
    	/*
    	    TestSliceGrowing: slice_test.go:30: 1 1
    		TestSliceGrowing: slice_test.go:30: 2 2
    		TestSliceGrowing: slice_test.go:30: 3 4
    		TestSliceGrowing: slice_test.go:30: 4 4
    		TestSliceGrowing: slice_test.go:30: 5 8
    		TestSliceGrowing: slice_test.go:30: 6 8
    		TestSliceGrowing: slice_test.go:30: 7 8
    		TestSliceGrowing: slice_test.go:30: 8 8
    		TestSliceGrowing: slice_test.go:30: 9 16
    		TestSliceGrowing: slice_test.go:30: 10 16
    	*/
    
    	//每次不够放的适合,都会将上次的扩展为之前的两倍,因此要使用类似于s2 = append(s2, 1) 因为是新的空间给s2,并将原来的数据拷贝过去。
    }
    
    func TestSliceShareMemory(t *testing.T) {
    	year := []string{"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}
    	q2 := year[3:6]
    	t.Log(q2, len(q2), cap(q2))
    	//输出结果为
    	//TestSliceShareMemory: slice_test.go:53: [Apr May Jun] 3 9,容量是直接到末尾的,所以是9.
    
    	summer := year[5:8]
    	t.Log(summer, len(summer), cap(summer))
    	summer[0] = "Unkonw"
    	t.Log(summer, len(summer), cap(summer))
    	t.Log(q2, len(q2), cap(q2))
    	//输出结果为
    	/*
    	    TestSliceShareMemory: slice_test.go:60: [Unkonw Jul Aug] 3 7
        	TestSliceShareMemory: slice_test.go:61: [Apr May Unkonw] 3 9
    	*/
    
    	//由于是共享的存储空间,因此summer的改动同时影响到了q2的值.
    }
    
    func TestSliceComparing(t *testing.T){
    	a := []int{1,2,3,4}
    	b := []int{1,2,3,4}
    
    	//会报错,nvalid operation: a == b (slice can only be compared to nil)
    	// if(a == b){
    	// 	t.Log("Can Compare")
    	// }
    
    	t.Log(a[2])
    	t.Log(b[2])
    	b[2] = 9
    	t.Log(a[2])
    	t.Log(b[2])
    
    	
    }
    
  • 相关阅读:
    网络协议
    面向对象三大特性之多态
    面向对象三大特性之封装
    面向对象三大特性之继承
    python面向对象编程
    常用模块之configpaser与shutil
    XML模块
    Python模块之OS,subprocess
    Python日志(logging)模块,shelve,sys模块
    Linux 配置 Nginx
  • 原文地址:https://www.cnblogs.com/dogtwo0214/p/13149572.html
Copyright © 2011-2022 走看看