【GO言語】　型ごとの特徴

# Go言語を学ぶ。
業務でGo言語が必要になってきたので、Go言語のアウトプットをこれからしていこうと思います。
超絶基礎的なところから始めて、アウトプットが必要だと感じた項目について記事にしていきます。
今回Udemyの『【Go入門】Golang基礎入門 + 各種ライブラリ + 簡単なTodoWebアプリケーション開発(Go言語)』の内容をもとに学習を進めていきます。
少しお金がかかりますが、私が書いていることよりも詳しく説明されていますので、ぜひこちら購入して学習してみてください。

https://www.udemy.com/course/golang-webgosql/?couponCode=ST11MT91624B

# 型ごとの特徴
型ごとに細かな特徴があるので特徴をまとめました。

## int型
- 表現方法
```golang
//明示的
var i int = 100

//暗黙的
i := 100
```

### int型の種類

| 型         | サイズ    | 範囲                                   |
|------------|-----------|----------------------------------------|
| `int`      | 実行環境依存（32bitまたは64bit） | 32bit環境では`-2^31` ～ `2^31-1`<br>64bit環境では`-2^63` ～ `2^63-1` |
| `int8`     | 8ビット    | `-128` ～ `127`                       |
| `int16`    | 16ビット   | `-32,768` ～ `32,767`                 |
| `int32`    | 32ビット   | `-2,147,483,648` ～ `2,147,483,647`   |
| `int64`    | 64ビット   | `-9,223,372,036,854,775,808` ～ `9,223,372,036,854,775,807` |

注意点として、それぞれ別の種類の型を指定して計算をした場合にエラーが発生します。
また、実行環境に依存した`int`(例えば64bit)と型を指定した`int64`についてもそれぞれ区別されます。
```golang
var i int32 = 100
var i2 int64 = 200

fmt.Println(i + i2);
//invalid operation: i + i2 (mismatched types int32 and int64)
```

### intの型変換

intの種類が違う場合に型変換というものが使えます。
型変換をすることで上記の計算を型が違ってもできるようになります。
```golang
var i int32 = 100 //32ビット
var i2 int64 = 200 //64ビット

fmt.Println(i + int32(i2))
// 300
```

## float型
- 表現方法
```golang
//明示的
var i(任意) float32 = 0.2

//暗黙的
i := 0.2
```

### int型の種類

| 型          | サイズ    | 精度と範囲                        |
|-------------|-----------|-----------------------------------|
| `float32`   | 32ビット   | 約7桁の有効数字、±1.18×10^−38 ～ ±3.4×10^38 |
| `float64`   | 64ビット   | 約15桁の有効数字、±2.23×10^−308 ～ ±1.8×10^308 |

float型は2つしかありませんが、float32を使うことはあまりありません。一般的には`float64`の方が高精度なため、`float64`を使うことが推奨されています。

floatもint型と同じくそれぞれ区別されます。
```golang
var fl32 float32 = 0.2 //32ビット
var fl64 float64 = 0.5 //64ビット

fmt.Println(fl32 + fl64)
//invalid operation: fl32 + fl64 (mismatched types float32 and float64)
```
ただ、こちらは何も指定せずにfloatを使った場合と`float64`を指定したもので計算ができます。
```golang
var fl  = 0.2 //指定なしの場合は64ビット
var fl64 float64 = 0.5 //64ビット

fmt.Println(fl + fl64)
//0.7
```


### floatの型変換

intと同じようにfloatも型変換が可能になっています。
```golang
var i fl32 = 0.2 //32ビット
var i2 fl64 = 0.5 //64ビット

fmt.Println(fl32 + float32(fl64))
// 0.7
```

## 論理値型
true（真）またはfalse（偽）という2つの値をもつ型です（それ以外特にいうことなし）。
```golang
//明示的
var t bool = true
var f bool = false

//暗黙的
t := true
f := false
```

## 文字列型
UTF-8エンコードされた文字列を表します。文字列はダブルクォーテーション(")で囲みます。
```golang
//明示的
var s string = "abc"

//暗黙的
s := "abc"
```

### バッククォーテーション（`）を使う

バッククォーテーションを使用することで、改行を含む文字列を表すことができます。
```golang
var s string = `abc
def
ghi`
//結果(改行も反映されている)
abc
                def
                ghi
```

### `"`を文字列として表示させたい時

2つの方法があり、好きな方でいいかと思います。
```golang
fmt.Println("\"")
fmt.Println(`"`)
```

## byte型
8ビットの符号なし整数型（uint8型）であり、主に文字列のバイト列を扱う際に使用される型のことです。別の言い方をするとbyte型は0から255の範囲の数値を取る整数型になります。
こちらは以下の記事を見ていただく方が圧倒的にわかりやすいのでぜひこちらをみてください。ただ、学習のために私自身でもまとめます。

https://qiita.com/s_zaq/items/a6d1df0d1bf79f5bcc2a


### byte型の中身

byte型の値はASCII文字に対応しています。以下のような基本的な英数字や記号、制御文字がそれぞれの値ごとにASCII文字が割り当てられています。

| コードポイント | 文字 |
|----------------|------|
| 32             | (スペース) |
| 33             | !    |
| 48             | 0    |
| 65             | A    |
| 97             | a    |
| 126            | ~    |

:::note info
ASCII文字は以下のように区分があります。

	•	制御文字（0〜31）：制御目的で使用される文字で、表示には関連しません。例：改行（Line Feed、LF）、キャリッジリターン（Carriage Return、CR）。
	•	印刷可能文字（32〜126）：実際に表示される文字や記号です。例：空白（スペース）、アルファベット（A〜Z、a〜z）、数字（0〜9）、記号（!、@、#など）。
	•	削除文字（127）：DEL（削除）文字で、通常はテキスト編集時に使われます。
:::

文字コードについては奥が深そうなのでここら辺でみなさまにぶん投げます。必要があれば、調べてみてください。

### byte型からstring型、string型からbyte型への変換
コードで見てもらう方が早いと思うのでコードで説明します。
先ほどの上記にあるASCII文字の表を使います。
```golang
//ASCII文字から「AAA!」にしたい
byte := []byte{65, 65, 65, 33}
fmt.Println(string(byteA))

//「AAA!」をASCII文字にしたい
byte := []byte("AAA!")
fmt.Println(byteB)
```

文字列から一部を取り出すことも可能です。
```golang
str := "ABC"

fmt.Println(str[0])
//65
fmt.Println(string(str[0]))
//A
```

## 配列型
同じデータ型の要素を連続して格納するためのデータ構造のことです。配列の型とサイズを指定すると利用でき、配列のサイズは変更することができません。サイズの指定は`[]`の中に数値を入れることで指定できます。
```golang
//明示的
var arr [3]int

//暗黙的
arr := [3]int{}
```
上記は値をセットしていないのでデフォルト値（0）が設定されます。上記の例だと`[0 0 0]`という風に出力されます。値を入れるときは`{}`内に値を書くことで代入できます。指定したサイズ以上の値は入れることができません。

```golang
//明示的
var arr [3]int = [3]int{1, 2, 3}

//暗黙的
arr := [3]int{1, 2, 3}
```

配列の要素数は`[]`で指定するといる説明をしましたが、実は`...`を用いることで要素数に応じてサイズを変更してくれるようになります。
```golang
arr := [...]int{1, 2, 3}
//サイズは3

arr := [...]int{1, 2, 3, 4, 5, 6}
//サイズは6
```

### 配列の操作
ここでは配列の中身を取り出す操作と更新する操作を説明します。
```golang
//配列の取得
arr := [6]int{1, 2, 3, 4, 5, 6} //サイズ6
fmt.Println(arr[2])   //3　インデックス番号の値を取る
fmt.Println(arr[2:4]) //[3 4]　インデックス番号が2から4の前までの値を取る
fmt.Println(arr[:2])  //[1 2]　インデックス番号が2の前までの値を取る
fmt.Println(arr[2:])  //[3 4 5 6]　インデックス番号が2から最後までの値を取る
fmt.Println(arr[:])   //[1 2 3 4 5 6]　全ての値を取る

//配列の更新
arr := [3]int{1, 2, 3}
arr[2] = 100 // {1, 2, 100}　インデックス番号の値が更新される
arr[4] = 100 //invalid argument: index 100 out of bounds [0:6]　サイズが3なのでエラー
```

## interface型
あらゆる型と互換性がある特殊な型。抽象化と多態性を提供しており、具体的なデータ型ではなく、特定のメソッドの集合を定義したものです。
あらゆる型と互換性があると説明がある通り、上記で説明した型が全て使えます。
```golang
var n interface{} //nil（初期値）
var i interface{} = 100 //100
var s interface{} = "ABC" //ABC
var b interface{} = true //true
var a interface{} = []int{1, 2, 3} //[1 2 3]
```

interface型はデータ特有の計算や演算はすることができないので注意。データを表示することのみ可能になっています。このような計算をしようとするとエラーが出ます。
```golang
var i interface{} = 100 //100
fmt.Println(200 + i)
//invalid operation: 200 + i (mismatched types int and interface{}) (compile)
```

## 型変換
### intとfloatの変換
intとfloatの変換については簡単にできます。
floatからintへの変換では小数点以下が切り捨てられます。
```golang
var i int = 10
var fl float64 = 1.5

//intからfloatへの変換
fl64 := float64(i) //10

//floatからintへの変換
int := int(fl64) //1
```

### 文字列型と数値型の変換
文字列と数値型を変換する際はGO言語の標準ライブラリのstrconvパッケージを用いることで変換します。
```golang
var i int = 100
var s string = "100"

//数値から文字列への変換
str, _ := strconv.Itoa(i) //int->string

//文字列から数値への変換
num, _ := strconv.Atoi(s) //string->int
```

:::note info
strconv.Itoa(), strconv.Atoi()よりも細かく変換するための関数も用意されています。気になった方は調べてみてください。
ParseInt
FormatInt
FormatFloat
:::

# まとめ
### 型は深い