My External Storage

Mar 6, 2020 - 2 minute read - Comments - go

[Go] 省略記号(...)を使った配列宣言の仕方

標準パッケージのコードを眺めていたら、珍しい書き方の部分を見つけた。
以下のように宣言すると、配列サイズを明示的に書かずに配列を宣言できる。

s := [...]int{1, 2, 3}

TL;DR

  • サイズが固定と分かっているときは配列を使いたい
  • [...]int{1, 2, 3}と書けば暗黙的にサイズが計算された配列を用意できる。
    • [...]int{n: 0}のように書けばn+1サイズの配列を用意することも可能
  • https://play.golang.org/p/nPFGSATYZwd
s := [...]int{1, 2, 3}
fmt.Printf("%T\n", s) // [3]int

l := [...]int{99: 1}
fmt.Printf("%T\n", l) // [100]int

配列リテラルの長さに省略記号(...)を指定する

標準パッケージのコードを調べていたら、[...]string{"http:", "https:"}のような宣言を見つけた。

func httpPrefix(s string) string {
  for _, prefix := range [...]string{"http:", "https:"} {
    if strings.HasPrefix(s, prefix) {
      return prefix
    }
  }
  return ""
}

何をしているかというと、固定長サイズ2の配列を宣言している。

プログラミング言語Go」の「4.1章 配列」の章で確認すると以下のように明記されていた。

配列リテラルで省略記号「...」が長さの場所に書かれている場合には、配列長は初期化子の数で決まります。

インデックスによる初期化にも対応しており、次のようにも書ける。

l := [...]int{99: 1}
fmt.Printf("%T\n", l) // [100]int

終わりに

Goはサイズ違いの配列は比較できない([2]int[3]intは比較できない)。
配列サイズも変更できないので、盲目的にスライスを使うことが多かった。
なので、「配列」の使い方は正直あまり覚えていなかった。

冒頭で引用したrange [...]string{"http:", "https:"}というようなrangeの回し方はスマートだと思った。
また、SHA256のような固定長のドメインロジックを使う機会も往々にしてあるので、自分のコードに取り込んでおきたい。

そして、また「プログラミング言語Go」に最初から書いてあった案件だったので、読み直しが必要だ。
(一度読み込んでいるはずなのに覚えていないことが多すぎる)

参考

関連記事