zoukankan      html  css  js  c++  java
  • 大数据开发-Go-数组,切片

    new()和make的区别

    二者看起来没什么区别,但是他们的行为不同,分别适用于不同的类型

    • new (T) 为每个新的类型 T 分配一片内存,初始化为 0 并且返回类型为 * T 的内存地址:这种方法 返回一个指向类型为 T,值为 0 的地址的指针,它适用于值类型如数组和结构体;它相当于 &T{}。

    • make(T) 返回一个类型为 T 的初始值,它只适用于 3 种内建的引用类型:切片、map 和 channel

    bytes包

    类型 []byte 的切片十分常见,Go 语言有一个 bytes 包专门用来解决这种类型的操作方法,比如bytes的buffer,就提供Read和Write的方法,读写未知长度的bytes时候最好用buffer,下面的例子类似于Java的StringBuilder的append方法

    var buffer bytes.Buffer
    for {
        if s, ok := getNextString(); ok { //method getNextString() not shown here
            buffer.WriteString(s)
        } else {
            break
        }
    }
    fmt.Print(buffer.String(), "
    ")
    
    

    slice重组

    知道切片创建的时候通常比相关数组小,例如:

    slice1 := make([]type, start_length, capacity)
    

    其中 start_length 作为切片初始长度而 capacity 作为相关数组的长度。

    这么做的好处是我们的切片在达到容量上限后可以扩容。改变切片长度的过程称之为切片重组 reslicing,做法如下:slice1 = slice1[0:end],其中 end 是新的末尾索引(即长度),如果想增加切片的容量,我们必须创建一个新的更大的切片并把原分片的内容都拷贝过来

    package main
    import "fmt"
    
    func main() {
        sl_from := []int{1, 2, 3}
        sl_to := make([]int, 10)
    
        n := copy(sl_to, sl_from)
        fmt.Println(sl_to)
        fmt.Printf("Copied %d elements
    ", n) // n == 3
    
        sl3 := []int{1, 2, 3}
        sl3 = append(sl3, 4, 5, 6)
        fmt.Println(sl3)
    }
    

    注意: append 在大多数情况下很好用,但是如果你想完全掌控整个追加过程,你可以实现一个这样的 AppendByte 方法:

    func AppendByte(slice []byte, data ...byte) []byte {
        m := len(slice)
        n := m + len(data)
        if n > cap(slice) { // if necessary, reallocate
            // allocate double what's needed, for future growth.
            newSlice := make([]byte, (n+1)*2)
            copy(newSlice, slice)
            slice = newSlice
        }
        slice = slice[0:n]
        copy(slice[m:n], data)
        return slice
    }
    

    Slice的相关应用

    假设 s 是一个字符串(本质上是一个字节数组),那么就可以直接通过 c := []byte(s) 来获取一个字节的切片 c。另外还可以通过 copy 函数来达到相同的目的:copy(dst []byte, src string) ,使用 substr := str[start:end] 可以从字符串 str 获取到从索引 start 开始到 end-1 位置的子字符串

    package main
    
    import "fmt"
    
    func main() {
        s := "u00ffu754c"
        for i, c := range s {
            fmt.Printf("%d:%c ", i, c)
        }
    }
    

    在内存中,一个字符串实际上是一个双字结构,即一个指向实际数据的指针和记录字符串长度的整数(见图 7.4)。因为指针对用户来说是完全不可见,因此我们可以依旧把字符串看做是一个值类型,也就是一个字符数组。

    字符串 string s = "hello" 和子字符串 t = s[2:3]

    • 修改字符串

      • Go 语言中的字符串是不可变的,也就是说 str[index] 这样的表达式是不可以被放在等号左侧的,如果必须要修改,必须要先将字符串转为字节数组,然后通过修改元素值来达到修改字符串的目的,最后要讲字节数组转回字符串格式
    • 字符串对比函数

      • Compare 函数会返回两个字节数组字典顺序的整数对比结果
    • 搜索及排序切片和数组

      • 标准库提供了 sort 包来实现常见的搜索和排序操作。您可以使用 sort 包中的函数 func Ints(a []int) 来实现对 int 类型的切片排序
    • 切片和垃圾回收

      切片的底层指向一个数组,该数组的实际容量可能要大于切片所定义的容量。只有在没有任何切片指向的时候,底层的数组内存才会被释放,这种特性有时会导致程序占用多余的内存
      吴邪,小三爷,混迹于后台,大数据,人工智能领域的小菜鸟。
      更多请关注
      file

  • 相关阅读:
    PSR-2 编码风格规范
    Git中删除冗余的分支
    linux下ssh连接缓慢详解
    pytest框架之fixture详细使用
    如何利用jenkins插件查看allure报告-----完整篇
    CentOS上安装配置Python3.7
    [Python]requests使用代理
    Selenium
    Python性能分析工具-cProfile
    subprocessf运行window程序
  • 原文地址:https://www.cnblogs.com/hulichao/p/15114259.html
Copyright © 2011-2022 走看看