4

スプライスを実装するための次のコードがあります (つまり、完全なバイト スライス、別のバイト スライス部分、部分で上書きしたい完全な位置を表す 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 バイト スライスの結合を行います。部分によって上書きされないフルの最初の部分、すべての部分、そしてフルの残りの部分です。これを行うためのより良い/より慣用的な方法はありますか? 標準ライブラリでこれを実装するメソッドを見つけることができませんでした。

4

4 に答える 4

6

部分が全体の境界内に完全にあることがわかっている場合は、コピー機能を使用できます。

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

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

遊び場

ただし、それは完全に上書きされます。オリジナルを保存したい場合は、追加機能を使用して最初にコピーを作成できます。

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)
}

遊び場

これには、部分が完全な境界内に収まる必要があるという元のコードの制限がまだあることに注意してください。

于 2012-11-24T19:10:59.793 に答える
0

appendビルトインを使用しないのはなぜですか?

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

これは非常に高速ではないかもしれませんが (大量のコピー)、かなり読みやすいです。

于 2012-11-24T19:57:10.610 に答える
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:]
}
于 2020-12-23T08:26:30.297 に答える