切片重组、复制与追加

slice(切片)代表变长的序列,序列中每个元素都有相同的类型。slice的底层引用一个数组对象,它并会实际复制一份数据,只是创建一个新的数据结构。在内存中,它是由三个部分构成的结构体:指针、长度和容量。指针指向第一个slice元素对应的底层数组元素的地址,长度对应slice中元素的数目,长度不能超过容量。容量一般是从slice的开始位置到底层数据的结尾位置。
这里写图片描述

切片重组

切片的长度可以用len(slice1)方法来获取,改变切片长度的过程称之为切片重组,重组时新的末尾索引不能超过设置的切片长度或当前切片的长度。例如:

package main

import "fmt"

func main() {
    slice1 := make([]string, 2, 5)
    slice1 = []string{"hello", "world"}
    slice2 := slice1[2:3] //3超出了切片slice1的长度
    fmt.Println(slice2)
}

切片重组时的长度可以大于len(arr),但是不能超出cap(arr),否则会导致panic异常。所以运行上面程序运行会报错,panic: runtime error: slice bounds out of range

切片的复制

如果想增加切片的容量,这时就需要将原切片的内容拷贝到一个新的更大容量的切片中。Go为我们提供了两种内建方法:append()和copy()。

1. append(slice []Type, elems …Type) []Type方法

append方法会将元素elems追加到切片slice的末尾,并返回更新后的数组。如果切片有足够的容量,则切片slice会重组以适应新的元素。如果slice切片没有容量来存放要添加的元素,那么append方法会分配一个新的底层数组。

package main

import "fmt"

func main() {
    slice1 := make([]string, 2, 5)
    slice1 = []string{"hello", "world"}
    slice2 := append(slice1,"china")
    fmt.Println(slice2)
}

2. copy(dst, src []Type) int方法

copy方法将会拷贝src切片到dst切片中,但是原切片和目标切片可能会重叠(覆盖dst切片中的相关元素)。copy方法执行后会返回复制的元素个数。

func Repeat(s string, count int) string {
    if count < 0 {
        panic("strings: negative Repeat count")
    } else if count > 0 && len(s)*count/count != len(s) {
        panic("strings: Repeat count causes overflow")
    }

    b := make([]byte, len(s)*count)
    bp := copy(b, s)
    for bp < len(b) {
        copy(b[bp:], b[:bp])
        bp *= 2
    }
    return string(b)
}

上面方法是strings包中的方法,它会将字符串s重复count次数,然后返回新的字符串。

切片的追加

由于append()方法传入的追加参数不能是切片,所以在添加多内容时可能不太方便。所以可以使用copy方法来实现。

package main

import "fmt"

func main() {
    slice1 := make([]string, 2, 5)
    slice1 = []string{"hello", "world"}
    slice2 := make([]string, 0)
    slice2 = []string{"china"}
    fmt.Println(appendSlice(slice1, slice2))
}

//将slice2追加到slice1上
func appendSlice(slice1 []string, slice2 []string) []string {
    newSlice := make([]string, len(slice1)+len(slice2))
    copy(newSlice, slice1)
    copy(newSlice[len(slice1):], slice2)
    return newSlice
}

猜你喜欢

转载自blog.csdn.net/benben_2015/article/details/80929421