Go言語で構造体のスライスを扱ってみる

Nov 30, 2016   #golang 

Go言語で構造体のスライスを扱おうとしたときに少し悩んだので、まとめておきます。

ここで構造体やスライスについて詳しく説明はしません。詳細はA Tour of Goなどに記載されているので、そちらをご確認下さい。 今回は、構造体を要素として持つスライスを扱う方法をまとめています。

いろいろな操作

  • 要素にする構造体
    今回の説明で使用する構造体は以下の通り定義されています。 社員番号(number)と名前(name)を持つ社員(employee)型です。スライスで複数人の社員情報をまとめて扱うようなイメージです。

    type employee struct {
    	number int
    	name   string
    }
    
  • スライスの作成
    以下のようにmake関数を使えば、要素数が0のemployee型のスライスを作成することが出来ます。

    employees := make([]employee, 0)
    

    スライスの作成と初期化をまとめて行うこともできます。

    employees := []employee{employee{1, "Taro"}}
    

    複数の要素を持つスライスを1行で書くことも可能です。

    employees := []employee{employee{1, "Taro"}, employee{2, "Jiro"}, employee{3, "Saburo"}}
    
  • 要素の追加
    既存のスライスに対して、要素を追加させるには以下のように記載します。

    employees = append(employees, employee{4, "Shiro"})
    
  • 要素の削除
    組込み関数にはスライスの要素を削除する仕組みは実装されていません。そのため、個別に関数を作成する必要があります。例としては、以下のような関数で要素の削除機能が実現できます。

    func delete(employees []employee, n int) []employee {
    	result := make([]employee, 0)
    	for i, v := range employees {
    		if i != n {
    			result = append(result, employee{v.number, v.name})
    		}
    	}
    	return result
    }
    
  • 要素のへのアクセス
    スライスの各要素のフィールドには個別にアクセスすることが出来ます。ここでは、先頭要素の各フィールドを出力してます。

    fmt.Println(employees[0].number)
    fmt.Println(employees[0].name)
    

    以下のように、フィールドの値を変更することも出来ます。

    employees[0].name = "Ichiro"
    
  • 全要素の参照
    for文を使うことで、スライスは内の全要素を順次参照することが出来ます。

    for _, v := range employees {
    fmt.Printf("number=%d, name=%s\n", v.number, v.name)
    }
    

おわりに

要素を追加する方法がわからず悩んだのですが、まとめてみると、複雑なことはなにもないですね。一晩悩んだのが悔しかったのでブログのネタとして使ってしまいます。
標準で要素の削除機能が用意されていないのは以外でした。それなりに使用頻度は高い気がするんですけどねぇ。

今回はポインタには一切触れていないので、第2弾があれば、その辺も記事にしたいところです。