🫙

【Go】多重スライスをforループを使わずにコピーする

2023/12/17に公開

概要

Goでスライスを複製する場合、[Golang]スライスの複製に便利な「copy」関数のサンプルと、直接代入した場合の罠のように、copy関数を使うことが多いと思いますが、このcopy関数は通常の配列にしか対応してないようです。forでループして最後の配列をcopyするようなロジックでも良いのですが、何か他に良い方法ないかなと思い少し調べたのでメモ書きします。

対応方針

stackoverflowのGolang multidimensional slice copyの記事にいくつか対応案が紹介されてますが、個人的にはencoding/gobのメソッドを使用したやり方が良いかなと感じました。これだと何重の配列が来ても対応できると思います。

実装サンプル

上記のstackoverflowの記事の内容そのままですが、以下に実装サンプルを記載します。

package main

import (
	"bytes"
	"encoding/gob"
	"fmt"
)

func main() {
	sliceCopy := func(in, out interface{}) {
		buf := new(bytes.Buffer)
		gob.NewEncoder(buf).Encode(in)
		gob.NewDecoder(buf).Decode(out)
	}

	a := [][][]int{
		{{1, 2, 3}, {4, 5, 6}, {7, 8, 9}},
		{{11, 12, 13}, {14, 15, 16}, {17, 18, 19}},
		{{21, 22, 23}, {24, 25, 26}, {27, 28, 29}},
	}

	var b [][][]int
	sliceCopy(a, &b)
	// bの値だけ変更する
	b[0][0][0] = 121

	fmt.Println(a)
	fmt.Println(b)
}

Discussion