[Golang] ネストしたスライスを使って、○×ゲーム描画部分のみのサンプルコードと解説

# 今日のコード
引用元のコード:[A Tour of Go / Slices of slices](https://go-tour-jp.appspot.com/moretypes/14)

```golang:○×ゲーム描画サンプル
package main

import (
	"fmt"
	"strings" // ①
)

func main() {
	// デフォルトの盤を準備…②
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}

	// ○×を入れていく…③
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
	board[0][2] = "X"

	// 全体を描画する…④
	for i := 0; i < len(board); i++ {
		fmt.Printf("%s\n", strings.Join(board[i], " "))
	}
	
}
```

```console:出力結果
X _ X
O _ X
_ _ O
```

# はじめに
今回は、A Tour of Goを勉強していて、本家の解説が少なくて分かりにくかった部分を共有したいと思います。

# 解説
サンプルコード内に①〜④の目印をつけています。
１つずつ調べたことを共有します。

## 1.stringsパッケージ
まず、①のパッケージについて。
これは、大変分かりやすくまとめてくれている[サイト](http://golang.jp/pkg/strings)があったので、解説はこちらに任せますが、要は**Go言語で文字列操作を、シンプルに行える関数を集めたパッケージ**のようです。
かなりよく使いそうなものがたくさん並んでいるので、僕と同じ入門者の方はサラッと見ておくと良いかと思います！

## 2.ネストされたスライスの定義

```golang:ネストされたスライスの定義
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
	}
```
この部分です。ちょっと個人的には、ワケわからなくなったので、整理しておきます。
通常の(ネストしていない)スライスを定義するには、

### ネストしていなければ…
```golang:ネストしていないスライス例
	x := []string{"a", "b", "c"}
	fmt.Println(x) // => [a b c]
```

スライスなので…

- `[]`の中には何も入れず、
- 格納するデータがstring型なので、それを記述し、
- 実際に、`{"a", "b", "c"}`このようにデータを格納している。

という感じです。

### これをネストさせると…

```golang:ネストしたスライス例
	y := [][]string{
		[]string{"a1", "a2", "a3"},
		[]string{"b1", "b2", "b3"},
		[]string{"c1", "c2", "c3"}
	}
	fmt.Println(y) // => [[a1 a2 a3] [b1 b2 b3] [c1 c2 c3]]
```
先ほどの

```golang
{"a", "b", "c"}
```

↑この部分が、

```golang
{
	[]string{"a1", "a2", "a3"},
	[]string{"b1", "b2", "b3"},
	[]string{"c1", "c2", "c3"}
}
```
↑こうなります。
ネスト(入れ子構造に)しているだけなので、落ち着いてよく見れば分かるかと思います。
大丈夫！…怖くないから…！！(笑)

### ポイントは`[][]string{}`←ここ
`[][]`ここで、ネストのスライスだと定義しているのかと思いきや、内側でもしっかり`[]`で定義。
ここは、もう決まり文句として捉えようと思います(笑)

あと、個人的に意外だった部分ですが、このネスト構造の一番外側の定義部分…
**stringなんですね…**
個人的には、中に入っているデータはスライスなので、ここは`[][]slice{}`(←適当)みたいなことになるのかなと考えていたのですが、違いました。

というか、そんな型ないですよね…（笑）

### ネストされるスライスの型は一律(？)

そこで予想されるのが、

```
[["あ", "い", "う"], [1, 2, 3], [true, false, false]]
```

↑こんな感じの、バラバラの型はネストして格納できなさそう…ということ。

つまり、**ネスト格納するデータは、同じ種類の型のもの入れられない**のではないかと、予想されます。
(違っていたらすみません。その場合はコメントでご指摘もらえると嬉しいです。)

実際、強引にやってみたら「intは無理っす」的なエラーがでました。

```golang:無理やり違う型をネストしてみたスライス
	board := [][]string{
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]string{"_", "_", "_"},
		[]int{1,2,3},
	}
```

```console:エラー文
cannot use []int literal (type []int) as type []string in array or slice literal
```

## 3.1行ずつ描画させて、ネストしたスライスのどこに格納されていくかを確認してみた

```golang
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
	board[0][2] = "X"
```
ここの部分です。
1行ずつ結果を出力して描画させることで、**どの階層の、どこに値を代入されせているか**を、確認しながら見ると理解が深まりましたので、共有しておきます。

```golang:(入力前)
```

```console
_ _ _
_ _ _
_ _ _
```

```golang:1行目
	board[0][0] = "X"
```

```console
X _ _
_ _ _
_ _ _
```

```golang:2行目
	board[0][0] = "X"
	board[2][2] = "O"
```

```console
X _ _
_ _ _
_ _ O
```

```golang:3行目
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
```

```console
X _ _
_ _ X
_ _ O
```

```golang:4行目
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
```

```console
X _ _
O _ X
_ _ O
```

```golang:5行目
	board[0][0] = "X"
	board[2][2] = "O"
	board[1][2] = "X"
	board[1][0] = "O"
	board[0][2] = "X"
```

```console
X _ X
O _ X
_ _ O
```

このような感じになります。
分かりやすくなりました。

## 4.全体strings.Join関数

```golang
	for i := 0; i < len(board); i++ {
		fmt.Printf("%s\n", strings.Join(board[i], " "))
	}
```
最後に、ここの関数についてざっくり解説です。
前提として、今回のスライスは**1階層目に3つのスライスが入っています**。

それらの描画方法として、ここの部分では
`fmt.Printf("%s\n", strings.Join(board[i], " "))`
この1行だけで、

- 1つずつのスライスを結合して、
- 間に` `(空文字)を入れて、
- string型として文字列にしています。

strings.Join関数…便利な関数です。

# さいごに

最後まで読んでいただき、ありがとうございました。
まだまだ入門者なので、間違いもあるかと思います。
ご指摘頂ければ、幸いです。