配列の基本


概要

配列とは同じ型の値を並べた連続したデータ構造です。

C_0015

使用理由

プログラムではランキングの点数など、同じ情報を複数用意したい場合が多々あります。

// ランキングのスコアを保存する変数
var socre_01 int
var score_02 int
var score_03 int
var score_04 int
var score_05 int

上のコードのように必要な分だけ宣言をすると、
数が増えれば増えるほど宣言だけでも面倒になり、
更にその値を入れ替えたり、全てを表示するとしたらもっと大変です。
このような時に配列を使用すると上記で書いた内容が
楽に書くことができるようになります。

書式

ここでは配列に関する書式について書いていきます。

宣言の書式

配列を使用するための宣言は以下のように書きます。

// 配列の書式
var 名前[配列の大きさ] 型
int型の値を10保存できる配列の宣言は以下のように書きます。
var score [5] int
宣言を行った配列は以下のようなデータのイメージになります。
go_0004

名称

配列には以下のような名称がついています。
go_0005
要素
要素とは配列宣言により作成された配列の1つ1つの値のことです。
配列はこの要素を参照したり、変更したりします。
要素数
要素数とは宣言によって作成された配列の大きさのことです。
そのまま「配列の大きさ」「配列の長さ」と呼ぶこともあります。
要素番号
要素番号とは作成した配列の要素数に応じで0から始まる連続した番号のことです。
「インデックス番号」や「インデックス」と呼ばれることもあります。
配列にアクセスする際はこの要素番号を指定して行います。
最初に書いていますが要素番号は0から始まり、要素数の-1までになります。

// socreの[0]からscore[4]まで使える
var score [5] int
score[0] = 10000;
score[1] = 1000;
score[2] = 100;
score[3] = 10;
score[4] = 1;	// ここまで

要素アクセスの書式

配列で用意した要素のどれかにアクセスして値を参照したり、
変更したりしたい場合は以下のように書きます。

配列名[要素番号]
要素のアクセスは配列名の後ろに[]を付けて、
その中にアクセスしたい要素番号を書きます。
例えば、要素番号3にアクセスして参照、代入をする場合は以下のように書きます。

score[3] = 100
fmt.Println(score[3])

宣言時初期化

宣言した際に要素の初期化をすることができます。
初期化の方法は複数用意されています。

まずは要素数を指定して、その要素数と同じ数だけ値を初期化する方法です。

// ①.要素数を指定して、その要素を全て初期化する
var score [3]int = [3]int {
	1,
	3,
	5,
}

次も要素数を指定しますが、初期化する値は要素数より少ない数で初期化する方法です。
この方法の場合、初期化されていない値は本来のゼロ値で初期化されます。

// ②.要素数を指定して、要素数以下で初期化する
var score [3]int = [3]int {
	1,
}

次は要素数を指定せずに初期化する方法です。
この手法の場合は「初期化した値の数 = 要素数」として配列が作成されます。
「:=」で初期化を行う必要があります。

// ③.初期化した値の数分だけ初期化して要素とする
// 今回の例では要素数は5
score := []int {
	1,
	3,
	10,
	100,
	2000,
}

最後は要素番号を指定して初期化する方法です。
初期値の前に要素番号を指定することで、指定した場所を初期化できます。
指定する際の[]の中には「...」を指定します。

// ④.要素番号を指定して初期化する
func main() {
	score := [...]float32{
		2: 1.3,
		5: 3.4,
	}

	// len(score)で要素数を取得できる
	for i := 0; i < len(score); i++ {
		fmt.Println(score[i])
	}
}

上の処理の結果は以下のようになり、要素番号2と5に初期値が設定されます。

// 処理結果
0
0
1.3
0
0
3.4

注意点

配列を使用するにあたっての注意点はいくつかありますが、
今回は「配列の数は途中で変更できない」「配列は値型」を紹介します。

配列の数は途中で変更できない

配列は最初に宣言した要素数からの変更はできません。
もし、配列の機能を使いつつ要素数を途中で変更したい場合は
スライスという機能を使用してください。

配列は値型

別の言語を知っている方は配列をポインタ型、参照型として
扱っていたと思いますが、Go言語の配列は値型です。
関数の引数で配列を指定した場合は配列の要素がコピーされることになり、
関数先で値を変更したとしても変化しないので注意してください。

// 実行してもscoreの値は変更されない
package main

import "fmt"

func ChageValue(array [3]float32) {
	fmt.Println("ChageValue関数実行")
	array[0] = 100
}

func main() {
	var score [3]float32 = [3]float32{
		1.3,
		3.4,
	}

	ChageValue(score)

	for i := 0; i < 3; i++ {
		fmt.Println(score[i])
	}
}

上の実行結果は以下のように表示されます。

// 実行結果
100
3.4
0

このように関数先で配列の要素を変更しても呼び出し元の配列の値は変わりません。