数组 和 切片

一、数组

        -连续存储的内存空间,因此不能添加元素,总不能内存往后挤吧
        -长度和类型在定义阶段就固定了(...的使用:可以接受任意长度,但是定义时取决于后面传入几个值,也是固定长度,见下方)
        -定义并初始化的时候,可以只指定某个位置的值-数组长度 len
        -数组的大小也是类型的一部分,大小不一样类型就不一样
        -数组是值类型,使用时时copy原数组,不会改变原数组,和python中不可变类型一样
        -循环数组
            -range
        -多维数组
            -var a [3][4]int 

var a = [...]int {x,c,v, }  // 不是变长数组,也不能说是不定长数组,定义时长度绝对是固定的只是依赖于后面传入几个值,这个数组大小就是3

 

//数组 在定义阶段,长度和类型就固定了,以后不能更改
package main
import "fmt"

func main() {
    //var a [5]int  //定义了一个长度为5的int类型数组
    //a[1]=100   //把2号位置放上100
    //fmt.Println(a)

    //定义并赋初值
        //var a [6]int=[6]int{1,2,3,4,5,6}
        //var a =[6]int{1,2,3}  //没传的是int的默认值0
        //a :=[6]int{1,2,3}
        //a[5]=100
        //fmt.Println(a)

        //先按位置传参,然后索引传参
            //a :=[100]int{1,2,98:99,87:88}
            ////a[-9]=19  不支持负索引
            //fmt.Println(a)

    //数组是值类型,所有的函数传参都是copy传递(和python中不可变类型一样)
            //a:=[4]int{1,2,3}
            //test6(a)
            //fmt.Println(a)

    //数组的长度 内置函数len
            //fmt.Println(len(a))
    //数组大小是类型一部分
            //var a [4]int=[4]int{1,2,}
            //var b [5]int=[5]int{4,5,}
            //a=b  //飘红 报错,长度不一样不能转换
            //fmt.Println(a,b)
    //与或非
    //&&   ||  !
        //a:=10
        //if !(a>9||a<6){
        //
        //}
    //数组迭代(遍历)
            //var a [4]int=[4]int{1,2,}
            //for i:=0;i<len(a);i++{
            //    fmt.Println(a[i])
            //}
    //通过range关键字迭代
        //var a [4]int=[4]int{1,2,}
        //for i,v:=range a {  // 索引和值都要
        ////for i:=range a {  // 只接受索引
        //    fmt.Println("------",i)
        //    fmt.Println(v)
        //}

    //多维数组
    var a [7][2]int
    a[0][1]=100
    fmt.Println(a)  //[[0 100] [0 0] [0 0] [0 0] [0 0] [0 0] [0 0]]
}
func test6(b [4]int)  {
    b[0]=100
    fmt.Println(b)
}

 二、切片

1.第一种方式,由数组切出来

package main

import "fmt"

func main () {
    //切片定义的第一种方式,由数组切出来
    var a [8]int=[8]int{1,2,3,4,5,6,7,8}  //定义数组
    ////是对数组的引用
    ////底层数组的修改会影响切片
    ////切片的修改也会影响底层数组
    var b []int=a[2:6]
    fmt.Println(b) //[3 4 5 6]
    a[2]=30
    fmt.Println(b)  //[30 4 5 6]
    b[1]=40
    fmt.Println(b) //[30 40 5 6]
    fmt.Println(a)  //[1 2 30 40 5 6 7 8]

    //更多用法,没有步长
    f:=a[:4] //[1 2 30 40]
    //f:=a[:]  //[1 2 30 40 5 6 7 8]
    fmt.Println(f)
}

2.第二种,直接定义

package main
import "fmt"
func main () {
    //第二种方式,直接定义并初始化,第一个数字是切片的长度 len,第二个数字是底层数组总长度,也就是切片的容量cap
        // 1.先拿一个切出来的切片示范,便于理解
        //    var a [8]int=[8]int{1,2,3,4,5,6,7,8}
        //    var b []int=a[2:6]
        //    fmt.Println(len(b))  //4
        //    fmt.Println(cap(b))  //6

        //2.直接定义并初始化
            var a []int=make([]int,3,4)
            fmt.Println(a)  //[0 0 0]
            fmt.Println(len(a))  //3
            fmt.Println(cap(a))  //4

    //切片空值是 nil 类型,不能传值
    //var a []int
    //if a==nil{
    //    fmt.Println("我是空的")
    //}
    //a[0]=10
    //fmt.Println(a)  //这样就报错了 ,相当于你定义了一个none然后给none传值,不报错才怪呢
}

3.切片 追加值

package main
import "fmt"
func main () {
    // 第一种切片:切来的
            var a [8]int=[8]int{0,1,2,3,4,5,6,7}
            var b []int=a[2:6]
            fmt.Println(len(b),b)  //4 [2 3 4 5 ]
            fmt.Println(cap(b))  //6  切片容量 :切别人的,容量不是整个数组长度,而是从切的位置到数组末尾
    
        //利用内置函数append  追加值
            b=append(b,555)
            b=append(b,666)
            fmt.Println(len(b),b)   //6  [2 3 4 5 555 666]
            fmt.Println(cap(b))  //6
        //当追加值后切片总长度不大于切片容量,切片值改变,底层数组对应值也跟着变
            b[0]=999 //切片修改
            fmt.Println(a)  //[0 1 999 3 4 5 555 666]
    
        //当追加溢出容量后,会重新申请新的一块内存,就会脱离数组控制,然后扩容至容量二倍,更改切片值,原数组值不再变
            b=append(b,777)
            fmt.Println(len(b),b)  //7 [999 3 4 5 555 666 777]
            fmt.Println(cap(b))  //12
    
            b[0]=9999
            fmt.Println(b)  //[9999 3 4 5 555 666 777]
            fmt.Println(a)  //[0 1 999 3 4 5 555 666]
// 第二种切片 自己建的
    var g =make([]int,3,4)
    fmt.Println(g)  //[0 0 0]
    g=append(g,4)
    fmt.Println(g)  //[0 0 0 4]
    fmt.Println(len(g))  //4
    fmt.Println(cap(g))  //4
    g=append(g,5)
    fmt.Println(len(g))  //5
    fmt.Println(cap(g))  //8
}

4.多维切片

package main
import "fmt"
func main () {
    //多维切片
    //        var a [][]string=make([][]string,2,3)  // 这个只能初始化外层的切片
    //        fmt.Println(a)  // [[] []]
    //
    //        a[0]=make([]string,2,3)  //初始化内层
    //        if a[0]==nil{ fmt.Println("xxxx")}
    //        fmt.Println(a)  //[[ ] []] a[0]初始化了,默认值为空,明显和a[1]不一样

    //多维切片初始化
    //        var a [][]string=[][]string{{"1","2"},{"3","4"}}
    //        fmt.Println(a)  // [[1 2] [3 4]]
    //        fmt.Println(len(a))  //2
    //        fmt.Println(cap(a))  //2
    //        a[0][1]="999"
    //        fmt.Println(a)  //[[1 999] [3 4]]
    //        a[1][0]="999"
    //        fmt.Println(a)  //[[1 999] [999 4]]
    
  //循环多维切片
  pls := [][]string {
  {"C", "C++"},
  {"JavaScript"},
  {"Go", "Rust"},
  }
  fmt.Println(pls) //[[C C++] [JavaScript] [Go Rust]]
  for _,v:=range pls {
  for _,v1:=range v{
  fmt.Println(v1)
  }
  }
}

5.切片的函数传递

package main
import "fmt"
func main () {

    //切片的函数传递
    var b =make([]int,3,4)
    test(b)
    fmt.Println(b)
}

func test(b []int)  {
    b[0]=999
    fmt.Println(b)
}

6.变长参数

package main
import "fmt"

//可变长参数
func main() {
    test1(1,2,3,4)
            //[1 2 3 4]
            //[]int
    var a =[]int{1,2,4,}
    test1(a...) //相当于打散了
            //[1 2 4]
            //[]int

    veggies := []string{"potatoes", "tomatoes", "brinjal"}
    fruits := []string{"oranges", "apples"}
    food := append(veggies, fruits...)
    fmt.Println("food:",food)  //food: [potatoes tomatoes brinjal oranges apples]

}

func test1(a ...int)  {
    fmt.Println(a)
    fmt.Printf("%T",a)  //看类型

}

7.copy函数

package main
import "fmt"

func main() {
    //copy函数
    var a =make([]int,3,10000)
    a[1]=99
    a[2]=888
    fmt.Println(a)  //[0 99 888]

    var b =make([]int,4,4)
    b[1]=100
    b[3]=300
    fmt.Println(b)  // [0 100 0 300]
    copy(b,a)  //拿a来覆盖b
    fmt.Println(b)  // [0 99 888 0]

    //var b =make([]int,2,4)
    //b[1]=100
    //fmt.Println(b)  // [0 100]
    //copy(b,a)
    //fmt.Println(b)  //[0 99]
}
posted @ 2019-12-11 22:03  www.pu  Views(249)  Comments(0)    收藏  举报