Go中的惯用切片拼接?

时间:2012-11-24 18:45:40

标签: go

我有以下用于实现拼接的代码(即,给定一个字节片满,另一个字节片部分,以及一个int pos表示我要用部分覆盖的完整位置):

package main

import (
    "fmt"
    "bytes"
)

func main() {
    full := []byte{0,0,0,0,0,0,0}
    part := []byte{1,1,1}

    newFull1 := splice(full, part, 2)
    fmt.Println(newFull1)
    // [0 0 1 1 1 0 0]

    newFull2 := splice(full, part, 3)
    fmt.Println(newFull2)
    // [0 0 0 1 1 1 0]
}

func splice(full []byte, part []byte, pos int) []byte {
    return bytes.Join([][]byte{full[:pos], part, full[len(full[:pos])+len(part):]}, []byte{})
}

基本上,我的方法执行3个字节切片的连接:完全的第一部分不被部分覆盖,全部部分,然后是完整的剩余部分。这样做有更好/更惯用的方法吗?我无法找到在标准库中实现此功能的方法。

3 个答案:

答案 0 :(得分:6)

如果您知道部分完全在完整范围内,则可以使用复制功能。

func main() {
    full := []byte{0, 0, 0, 0, 0, 0, 0}
    part := []byte{1, 1, 1}

    copy(full[2:], part)
    fmt.Println(full)
}

playground

虽然覆盖了全部。如果您想保留原件,可以先使用追加功能制作副本。

func main() {
    full := []byte{0, 0, 0, 0, 0, 0, 0}
    part := []byte{1, 1, 1}

    newFull := append([]byte{}, full...)
    copy(newFull[2:], part)
    fmt.Println("newFull:      ", newFull)
    fmt.Println("original full:", full)
}

playground

请注意,这仍然具有原始代码的限制,该部分必须符合完整范围。

答案 1 :(得分:0)

为什么不使用内置的append

func splice(full, part []byte, pos int) (ret []byte) {
    ret = append(full[:pos], part...)
    return append(ret, full[pos:]...)
}

这可能不是很快(大量复制),但它非常易读。

答案 2 :(得分:0)

字符串的变体(拆分/拼接/连接)。

func stringSplice(full string, start, deleteCount int, item string) (ret string) {
    if start > len(full) {
        return full + item
    }
    ret = full[:start] + item

    if start+deleteCount > len(full) {
        return ret
    }
    return ret + full[start+deleteCount:]
}