zoukankan      html  css  js  c++  java
  • go 切片

    切片定义

    切片是基于数组类型做的一层封装。它非常灵活,可以自动扩容。

    var a []int
    //定义一个int类型的空切片

    切片初始化, a[start:end]创建一个包括从start到end-1的切片。

    package main
    import ( 
        "fmt"
    )
    func main() { 
        a := [5]int{76, 77, 78, 79, 80}
        var b []int = a[1:4] //基于数组a创建⼀个切⽚,包括元素a[1] a[2] a[3]
        fmt.Println(b)
    }

    切片初始化方法2

    package main
    import ( 
      "fmt"
    )
    func main() { 
      c := []int{6, 7, 8} //创建⼀个数组并返回⼀个切⽚
      fmt.Println(c)
    }

    数组切片的基本操作

    切片基本操作
    a) arr[start:end]:包括start到end-1(包括end-1)之间的所有元素
    b) arr[start:]:包括start到arr最后一个元素(包括最后一个元素)之间的所有元素
    c) arr[:end]:包括0到end-1(包括end-1)之间的所有元素
    d) arr[:]:包括整个数组的所有元素

    package main
    
    import (
        "fmt"
    )
    
    func testSlice0() {
        var a []int
        if a == nil {
            fmt.Printf("a is nil
    ")
        } else {
            fmt.Printf("a = %v
    ", a)
        }
        a[0] = 100
    }
    
    func testSlice1() {
        a := [5]int{1, 2, 3, 4, 5}
        var b []int
        b = a[1:4]
        fmt.Printf("slice b:%v
    ", b)
        fmt.Printf("b[0]=%d
    ", b[0])
        fmt.Printf("b[1]=%d
    ", b[1])
        fmt.Printf("b[2]=%d
    ", b[2])
        fmt.Printf("b[3]=%d
    ", b[3])
    }
    
    func testSlice2() {
        a := []int{1, 2, 3, 4, 5}
    
        fmt.Printf("slice a:%v type of a:%T
    ", a, a)
    }
    
    func testSlice3() {
        a := [5]int{1, 2, 3, 4, 5}
        var b []int
        b = a[1:4]
        fmt.Printf("slice b:%v
    ", b)
    
        // c := a[1:len(a)]
        c := a[1:]
        fmt.Printf("slice c:%v
    ", c)
        //d := a[0:3]
        d := a[:3]
        fmt.Printf("slice d:%v
    ", d)
        // e  := a[0:len(a)]
        e := a[:]
        fmt.Printf("slice e:%v
    ", e)
    }
    
    func testSlice4() {
        a := [...]int{1, 2, 3, 4, 5, 7, 8, 9, 11}
    
        fmt.Printf("array a:%v type of a:%T
    ", a, a)
        b := a[2:5]
        fmt.Printf("slice b:%v type of b:%T
    ", b, b)
        /*
            b[0] = b[0] + 10
            b[1] = b[1] + 20
            b[2] = b[2] + 30
        */
        /*
            for index, val := range b {
                fmt.Printf("b[%d]=%d
    ", index, val)
            }
        */
        for index := range b {
            b[index] = b[index] + 10
        }
        fmt.Printf("after modify slice b, array a:%v type of a:%T
    ", a, a)
    }
    
    func testSlice5() {
        a := [...]int{1, 2, 3}
        s1 := a[:]
        s2 := a[:]
        s1[0] = 100
        fmt.Printf("a=%v s2=%v
    ", a, s2)
        s2[1] = 200
        fmt.Printf("a=%v s1=%v
    ", a, s1)
    }
    
    func main() {
        //testSlice0()
        //testSlice1()
        //testSlice2()
        //testSlice3()
        //testSlice4()
        testSlice5()
    }
    test

    切片修改

    package main
    import ( 
     "fmt"
    )
    func main() { 
     //创建一个数组,其中[…]是编译器确定数组的⻓度,darr的长度是9
     darr := [...]int{57, 89, 90, 82, 100, 78, 67, 69, 59}
     //基于darr创建一个切片dslice,包括darr[2],darr[3],darr[4]三个元素
     dslice := darr[2:5]
     fmt.Println("array before",darr)
     for i := range dslice {
     //对于dslice中每个元素进行+1,其实修改是darr[2],darr[3],darr[4]
     dslice[i]++
     }
     fmt.Println("array after",darr)
    }
    package main
    import ( 
     "fmt"
    )
    func main() { 
     numa := [3]int{78, 79 ,80}
     //创建一个切片,包含整个数组的所有元素
     nums1 := numa[:]
     nums2 := numa[:]
     fmt.Println("array before change 1",numa)
     nums1[0] = 100
     fmt.Println("array after modification to slice nums1", numa)
     nums2[1] = 101
     fmt.Println("array after modification to slice nums2", numa)
    }

    使用make创建切片

    package main
    import ( 
        "fmt"
    )
    func main() { 
        //[]中没有长度
        i := make([]int, 5, 5)
        fmt.Println(i)
    }

    切片的长度和容量

    package main
    import ( 
        "fmt"
    )
    func main() { 
        fruitarray := […]string{
            "apple", "orange", "grape",
            "mango", "water melon",
            "pine apple", "chikoo"}
        fruitslice := fruitarray[1:3]
        //长度是2,容量is 6
        fmt.Printf("length of slice %d capacity %d",
        len(fruitslice), cap(fruitslice))
    }
    package main
    
    import "fmt"
    
    func testMake1() {
        var a []int
        a = make([]int, 5, 10)
        a[0] = 10
        //a[1] = 20
        fmt.Printf("a=%v addr:%p len:%d cap:%d
    ", a, a, len(a), cap(a))
        a = append(a, 11)
        fmt.Printf("a=%v addr:%p len:%d cap:%d
    ", a, a, len(a), cap(a))
    
        for i := 0; i < 8; i++ {
            a = append(a, i)
            fmt.Printf("a=%v addr:%p len:%d cap:%d
    ", a, a, len(a), cap(a))
        }
        //观察切片的扩容操作,扩容的策略是翻倍扩容
        a = append(a, 1000)
        fmt.Printf("扩容之后的地址:a=%v addr:%p len:%d cap:%d
    ", a, a, len(a), cap(a))
    }
    /*
    a=[10 0 0 0 0] addr:0xc0000860a0 len:5 cap:10
    a=[10 0 0 0 0 11] addr:0xc0000860a0 len:6 cap:10
    a=[10 0 0 0 0 11 0] addr:0xc0000860a0 len:7 cap:10
    a=[10 0 0 0 0 11 0 1] addr:0xc0000860a0 len:8 cap:10
    a=[10 0 0 0 0 11 0 1 2] addr:0xc0000860a0 len:9 cap:10
    a=[10 0 0 0 0 11 0 1 2 3] addr:0xc0000860a0 len:10 cap:10
    a=[10 0 0 0 0 11 0 1 2 3 4] addr:0xc000098000 len:11 cap:20
    a=[10 0 0 0 0 11 0 1 2 3 4 5] addr:0xc000098000 len:12 cap:20
    a=[10 0 0 0 0 11 0 1 2 3 4 5 6] addr:0xc000098000 len:13 cap:20
    a=[10 0 0 0 0 11 0 1 2 3 4 5 6 7] addr:0xc000098000 len:14 cap:20
    扩容之后的地址:a=[10 0 0 0 0 11 0 1 2 3 4 5 6 7 1000] addr:0xc000098000 len:15 cap:20
    */
    
    func testMake2() {
        var a []int
        a = make([]int, 5, 10)
        //a[5] = 100
        a = append(a, 10)
        fmt.Printf("a=%v
    ", a)
    
        b := make([]int, 0, 10)
        fmt.Printf("b=%v len:%d cap:%d
    ", b, len(b), cap(b))
        b = append(b, 100)
        fmt.Printf("b=%v len:%d cap:%d
    ", b, len(b), cap(b))
    }
    
    func main() {
        // testMake1()
        testMake2()
    }

    切片的再切片

    package main
    
    import "fmt"
    
    func reslice() {
        a := [...]int{1, 2, 3, 4, 5, 6, 4, 7, 8}
        b := a[2:4]
        fmt.Printf("b = %d len(b) = %d cap(b)=%d
    ", b, len(b), cap(b))
        c := b[:cap(b)]
        fmt.Printf("c = %d len(c) = %d cap(c)=%d
    ", c, len(c), cap(c))
    }
    
    func main() {
        reslice()
    }
    
    /*
    b = [3 4] len(b) = 2 cap(b)=7
    c = [3 4 5 6 4 7 8] len(c) = 7 cap(c)=7
    */

     计算容量

    package main
    
    import "fmt"
    
    func testCap() {
        a := [...]int{1, 2, 3, 4, 5, 6, 7}
        b := a[1:3]
        fmt.Print("b= %v  len(b) = %d, cap(b) = %d
    ", b, len(b), cap(b)) // 切片的容量 等于 原始素组的长度 减去 切片开始的索引
    }
    
    func main() {
        testCap()
    }
    package main
    import ( 
        "fmt"
    )
    func main() { 
        fruitarray := […]string{
             "apple", "orange", "grape", "mango",
            "water melon", "pine apple", "chikoo"}
        fruitslice := fruitarray[1:3]
        //⻓度是2, 容量是6
        fmt.Printf("length of slice %d capacity %d
    ",
        len(fruitslice), cap(fruitslice))
        //再重新进⾏切⽚,不能⼤于数组fruitarray的⻓度,否则越界
        fruitslice = fruitslice[:cap(fruitslice)]
        fmt.Println("After re-slicing length is”,
        len(fruitslice), "and capacity is",cap(fruitslice))
    }        

    append操作

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        cars := []string{"Ferrari", "Honda", "Ford"}
        //长度和容量都等于3
        fmt.Println("cars:", cars, "has old length", len(cars), "and capacity", cap(cars))
        cars = append(cars, "Toyota")
        //容量等于6
        fmt.Println("cars:", cars, "has new length",
            len(cars), "and capacity", cap(cars))
    }
    /*
    cars: [Ferrari Honda Ford] has old length 3 and capacity 3
    cars: [Ferrari Honda Ford Toyota] has new length 4 and capacity 6
    */

    空切片

    package main
    import ( 
        "fmt"
    )
    func main() { 
        //定义names是一个空切片,长度和容量都等于0
        //不能对空切片进行访问,否则panic
        var names []string
         if names == nil {
              fmt.Println("slice is nil going to append")
              names = append(names, "John", "Sebastian", "Vinay")
              fmt.Println("names contents:",names)
        }
    }    
    package main
    
    import "fmt"
    
    func test() {
        var a []int
    
        fmt.Printf("addr = %p len=%d  cap =%d
    ", a, len(a), cap(a))
        // a[0]=100  报错
    
        if a == nil {
            fmt.Printf("a is nil
    ")
        }
    
        a = append(a, 100)
        fmt.Printf("addr = %p len=%d  cap =%d
    ", a, len(a), cap(a))
        a = append(a, 200)
        fmt.Printf("addr = %p len=%d  cap =%d
    ", a, len(a), cap(a))
        a = append(a, 300)
        fmt.Printf("addr = %p len=%d  cap =%d
    ", a, len(a), cap(a))
        a = append(a, 400)
        fmt.Printf("addr = %p len=%d  cap =%d
    ", a, len(a), cap(a))
    
    }
    /*
    addr = 0x0 len=0  cap =0
    a is nil
    addr = 0xc0000100e0 len=1  cap =1
    addr = 0xc000010100 len=2  cap =2
    addr = 0xc00000a3c0 len=3  cap =4
    addr = 0xc00000a3c0 len=4  cap =4
    */
    
    func main() {
        test()
    }

    append一个切片

    package main
    import ( 
     "fmt"
    )
    func main() { 
     veggies := []string{"potatoes","tomatoes","brinjal"}
     fruits := []string{"oranges","apples"}
     //fruits后面的3个点表示展开fruits切片成一个个元素
     food := append(veggies, fruits...)
     fmt.Println("food:",food)
    }
    // food: [potatoes tomatoes brinjal oranges apples]
    package main
    
    import "fmt"
    
    func test() {
        var a []int = []int{1, 2, 3}
        b := []int{4, 5, 6}
        c := append(a, b...)
        fmt.Printf("a=%v
    ", a)
        fmt.Printf("b=%v
    ", b)
        fmt.Printf("c=%v
    ", c)
    }
    /*
    a=[1 2 3]
    b=[4 5 6]
    c=[1 2 3 4 5 6]
    */
    
    func main() {
        test()
    }

     切片传参

    package main
    
    import (
        "fmt"
    )
    
    //在函数内部修改numbers切⽚的值
    func subtactOne(numbers []int) {
        for i := range numbers {
            numbers[i] -= 2
        }
    }
    func main() {
        nos := []int{8, 7, 6}
        fmt.Println("slice before function call", nos)
        subtactOne(nos)
        //nos修改生效了,说明切片是引用类型
        fmt.Println("slice after function call", nos)
    }
    /*
    slice before function call [8 7 6]
    slice after function call [6 5 4]
    */
    package main
    
    import "fmt"
    
    func testSum(a []int) int {
        sum := 0
        for _, v := range a {
            sum += v
        }
        return sum
    }
    
    func testChange(a []int) {
        a[0] = 1000
    }
    
    func main() {
        a := [...]int{1, 2, 3, 4, 5, 6}
        // sum := testSum(a[:])
        // fmt.Printf("sum = %d", sum) // 21
    
        fmt.Printf("a=%v
    ", a)
        testChange(a[:])
        fmt.Printf("a=%v", a)
    
        /*
        a=[1 2 3 4 5 6]
        a=[1000 2 3 4 5 6]
        */
    }

    切片拷贝

    package main
    
    import (
        "fmt"
    )
    
    func main() {
        veggies := []string{"potatoes", "tomatoes", "brinjal"}
        fruits := []string{"oranges", "apples"}
        copy(veggies, fruits)
        fmt.Println(veggies, fruits) //[oranges apples brinjal] [oranges apples]
    }
    package main
    
    import "fmt"
    
    func testCopy() {
        a := []int{1, 2, 3}
        b := []int{4, 5, 6}
    
        copy(a, b)
        fmt.Printf("a = %v
    ", a) // [4,5,6]
        fmt.Printf("b = %v
    ", b) // [4,5,6]
    
        c := []int{1, 2}
        d := []int{4, 5, 6}
    
        e := copy(c, d)
        fmt.Printf("c = %v
    ", c) // [4,5]
        fmt.Printf("d = %v
    ", d) // [4,5,6]
        fmt.Printf("e = %v
    ", e) // 2
    
        b[0] = 100
        fmt.Printf("a = %v
    ", a) // [4,5,6]
        fmt.Printf("b = %v
    ", b) // [100 5 6]
    
        aa := [...]int{1, 2, 3, 4, 5, 6}
        bb := aa[:]
        cc := []int{10, 20, 30}
        copy(bb, cc)
        fmt.Printf("aa = %v
    ", aa) // [10 20 30 4 5 6]
        fmt.Printf("bb = %v
    ", bb) // [10 20 30 4 5 6]
        fmt.Printf("cc = %v
    ", cc) // [10 20 30]
    
    }
    
    func main() {
        testCopy()
    }

    切片遍历

    var a [3]int
    a[0] = 10
    a[1] = 20
    a[2] = 30
    b := a[:]
    for index, val := range b {
    }
    //和数组遍历一样

    make和new区别

     make为内建类型slice、map和channel分配内存。

    //初始化一个切片
    s := make([]int, 10, 30)

     new用于各种类型的内存分配,new返回是一个指针。

     

  • 相关阅读:
    [WCF权限控制]模拟(Impersonation)与委托(Delegation)[上篇]
    深入剖析授权在WCF中的实现[共14篇]
    模拟在WCF中的应用
    WCF服务端运行时架构体系详解[下篇]
    WCF运行时框架的构建与扩展[共10篇]
    如何在EHAB(EntLib)中定义”细粒度”异常策略?
    WCF服务端运行时架构体系详解[续篇]
    《WCF服务编程》关于“队列服务”一个值得商榷的地方
    vs2005入门 之 结构化数据类型[一](数组)[视频]
    Atlas入门UpdateProgress(利用GridView翻页)[视频]
  • 原文地址:https://www.cnblogs.com/ctztake/p/10324561.html
Copyright © 2011-2022 走看看