いろいろ備忘録日記

主に .NET とか Go とか Python絡みのメモを公開しています。

Goメモ-88 (スライスから配列にコピーする)

概要

Goを勉強し始めた人からよく聞く質問がこれなので、ついでにここにメモです。

やり方としては、ビルドイン関数の copy(dst, src) を使います。

golang.org

copy関数のシグネチャは以下のようになってます。

func copy(dst, src []Type) int

んで、関数の説明の部分には以下のように記載されています。

The copy built-in function copies elements from a source slice into a destination slice. (As a special case, it also will copy bytes from a string to a slice of bytes.)

ドキュメント見ると、スライスをコピーする関数って書いてあるので、配列には使えないって思うんだと思います。

配列とスライスは異なるものなんですが、配列をスライスにするのは出来ます。スライスは配列の一部分をスライスして見せてくれているものと思いましょう。

var array = [4]byte{1, 2, 3, 4}

という4要素の配列があったとして

var slice1 []byte = array[:2]

とすると [1, 2] というスライスになります。元の配列の先頭から2番目の要素までをスライスしている状態ですね。

なので

var slice2 []byte = array[2:]

とすると3番目の要素から最後の要素までをスライスしたことになります。

てことは

var slice3 []byte = array[:]

とすると、最初から最後までのスライスが手に入ります。

copy() は、スライスを要求するので

copy(array[:], slice)

ってやるとスライスを配列にコピーしたことになります。

勿論、forでスライス回して、配列に一つずつ入れていっても正解ですが、こっちの方が楽かなって個人的には思ってます。

サンプル

package array

import (
    "github.com/devlights/gomy/output"
)

// CopyFromSlice -- スライスから配列へコピーするサンプルです。
func CopyFromSlice() error {
    // ----------------------------------------------
    // スライスから配列へコピー
    //
    // ビルドインのcopy()を利用すれば良い。
    //
    // [参考]
    // https://stackoverflow.com/a/30285971
    // ----------------------------------------------
    var (
        slice = []int{1, 2, 3, 4, 5}
        array = [4]int{}
    )

    output.Stdoutl("[slice]", slice)
    output.Stdoutl("[array]", array)
    output.StdoutHr()

    // copy(array[:], slice[:len(array)])としても問題はないが
    // copy() は、コピーする要素数を指定した2つの引数の少ない方で
    // 決定してコピーしてくれるので、以下で良い
    copy(array[:], slice)

    output.Stdoutl("[slice]", slice)
    output.Stdoutl("[array]", array)

    return nil
}

try-golang/array_copy_from_slice.go at master · devlights/try-golang · GitHub

実行すると以下のようになります。

$ make run
ENTER EXAMPLE NAME: array_copy_from_slice
[Name] "array_copy_from_slice"
[slice]              [1 2 3 4 5]
[array]              [0 0 0 0]
-------------------------------------------------- 
[slice]              [1 2 3 4 5]
[array]              [1 2 3 4]


[Elapsed] 191.462µs

参考情報

stackoverflow.com

blog.golang.org

blog.golang.org


過去の記事については、以下のページからご参照下さい。

  • いろいろ備忘録日記まとめ

devlights.github.io

サンプルコードは、以下の場所で公開しています。

  • いろいろ備忘録日記サンプルソース置き場

github.com

github.com

github.com