• golang学习笔记——数据和切片


    一维数组赋值
    package main
     
    import (
        "fmt"
    )
     
    func main() {
        //全部赋值
        var a [5]int = [5]int{1, 2, 3, 4, 5}
        fmt.Println("a = ", a)
     
        //部分赋值
        b := [...]int{3, 4, 5}
        fmt.Println("b = ", b)
     
        //指定元素赋值
        c := [5]int{1: 2, 3: 4}
        fmt.Println("c = ", c)
    }
     
    二维数组赋值
    package main
     
    import (
        "fmt"
    )
     
    func main() {
        a := [2][3]int{
             {3, 2, 1},
             {1, 2, 3},
        }
        fmt.Println("a = ", a)
    }
     
    数组做形参
    package main
     
    import (
        "fmt"
    )
     
    func modify(p *[5]int) {
        (*p)[0] = 100
    }
     
    func main() {
        a := [5]int{1, 2, 3, 4, 5}
        modify(&a)
        fmt.Println("a = ", a)
    }
     
    切片
    • 声明
    //自动推导类型
    s1 := []int{1, 2, 3, 4}
    fmt.Println("s1 = ", s1)
    //借助make函数 make(切片类型,长度,容量)
    s2 := make([]int, 5, 6)
    fmt.Printf("s2 : len(s2) = %d,cap(s2) = %d ", len(s2), cap(s2))
    • 截取切片
            low:代表截取开始的开始下标(包含)
            height:代表截取结束的下标(不包含)
            max:代表原始数组的长度或原始切片的最大容量
    sl := [6]int{1, 2, 3, 4, 5, 10}
    // sl[low:heigh:max]
    s := sl[2:3:6]
    fmt.Println("s = ",  s)
    • 切片的容量和长度
    切片的长度是指切片中实际包含的元素个数,而容量是指切片能容纳的最大元素个数,为什么要设计长度和容量这两个参数而不是使用一个参数代替呢?在这里容量是可以根据切片里的元素增加而增加的,并且是成倍数增涨,切片容量的增加意味着需要重新调整分配的内存空间,也就会造成多余的性能消耗。所以初始化切片时合理的设置容量的大小,能有效地降级重新分配变量内存而带来的性能消耗
    package main
     
    import "fmt"
     
    func main() {
       array := make([]int, 1, 3)
       fmt.Printf("初始化切换的长度:%d,容量 %d ", len(array), cap(array))
       for i := 0; i < 10; i++ {
          array = append(array, i)
          fmt.Printf("初始化切换的长度:%d,容量 %d ", len(array), cap(array))
       }
    }
    //************输出*************
    初始化切换的长度:1,容量 2
    初始化切换的长度:2,容量 2
    初始化切换的长度:3,容量 4
    初始化切换的长度:4,容量 4
    初始化切换的长度:5,容量 8
    初始化切换的长度:6,容量 8
    初始化切换的长度:7,容量 8
    初始化切换的长度:8,容量 8
    初始化切换的长度:9,容量 16
    初始化切换的长度:10,容量 16
    初始化切换的长度:11,容量 16
    • append函数(在切片末尾添加数据)
    s := []int{1, 2, 3}
    s = append(s, 5, 6)
    fmt.Println("sl = ", s)
    • append扩容时如果最终切片的长度大于原先切片的容量,则新切片的最大容量会变为原切片容量的两倍。且如果这个值扔不能满足新切片的需求时以长度2递增
    s := []int{1, 2}
    s = append(s, 5, 6, 7, 4, 5, 6)
    fmt.Println("s leng = ", cap(s)) //s leng = 8
    s = append(s, 4, 5, 6, 7, 8)
    fmt.Println("s leng = ", cap(s)) // s leng = 16
    • copy(dst,src)  将src切片复制给dst切片复制的长度以dst的容量为准直到src切片所有元素
    s := []int{1, 2, 3, 4, 5, 6, 7}
    s2 := []int{10, 11, 12, 13, 14, 15, 16, 17}
    copy(s[4:], s2)
    fmt.Println("s = ", s) // s = [1 2 3 4 10 11 12]
    • 注意
    1、切片本身不包含任何数据。它仅仅是底层数组的一个上层表示。对切片进行的任何修改都将反映在底层数组中。
    2、切片的长度是指切片中元素的个数。切片的容量是指从切片的起始元素开始到其底层数组中的最后一个元素的个数。
    3、切片是不声明长度的数组
    • 切片是指针变量,数组是值变量
    package main
     
    import (
        "fmt"
    )
     
    func modify_arr(p [6]int) {
        p[0] = 123
    }
     
    func modify_slice(p []int) {
        p[0] = 123
    }
     
    func main() {
     
        numbers_arr := [6]int{1, 2, 3, 4, 5, 6}
        modify_arr(numbers_arr)
        fmt.Println(numbers_arr) //输出 [1 2 3 4 5 6]
     
        numbers_slice := []int{1, 2, 3, 4, 5, 6}
        modify_slice(numbers_slice)
        fmt.Println(numbers_slice) //输出 [123 2 3 4 5 6]
     
    }
    • 内存优化
    /**
    *    切片保留对底层数组的引用。只要切片存在于内存中,数组就不能被垃圾回收。这在内存管理方面可能是值得关注的。假设我们有一个
    * 非常大的数组,而我们只需要处理它的一小部分,为此我们创建这个数组的一个切片,并处理这个切片。这里要注意的事情是,数组仍然 
    * 存在于内存中,因为切片正在引用它。解决该问题的一个方法是使用 copy 函数 func copy(dst, src []T) int 来创建该切片的一个 
    * 拷贝。这样我们就可以使用这个新的切片,原来的数组可以被垃圾回收。
    **/
    package main
     
    import (  
        "fmt"
    )
     
    func countries() []string {  
        countries := []string{"USA", "Singapore", "Germany", "India", "Australia"}
        neededCountries := countries[:len(countries)-2]
        countriesCpy := make([]string, len(neededCountries))
        copy(countriesCpy, neededCountries) //copies neededCountries to countriesCpy
        return countriesCpy
    }
    func main() {  
        countriesNeeded := countries()
        fmt.Println(countriesNeeded)
    }
     
     
     
  • 相关阅读:
    C# 抽象(3)
    C# 抽象(2)
    C# 抽象
    将 varchar 值 'ACCE5057EC423F7C' 转换成数据类型 int 时失败
    处理程序“ExtensionlessUrlHandler-Integrated-4.0”在其模块列表
    方法调用 Controller的Action 参数
    A problem has been detected and windows has been shut down to prevent damage to your computer.他么啥意思?看这里!【蓝屏】
    自己搭建了一个简单实用的Web版记事本
    GRPC
    Ocelot Consul
  • 原文地址:https://www.cnblogs.com/itsuibi/p/14456363.html
Copyright © 2020-2023  润新知