【Go入門】Golang基礎入門＋αの備忘録#2


# はじめに
[【Go入門】Golang基礎入門＋αの備忘録](https://qiita.com/sabotenten/items/aa588f82465545d9a0ec/ "")の続き。
この記事は以下のUdemyコースの学習記録です。

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

重要だと思った部分や感想、復習用に何を学んだかを書いていきます。
## セクション8：制御構文
基本的な制御構文を学んだ。
### for
1\. breakは一番近いfor文を抜ける
2\. 無限ループ、条件式付きfor、古典的for、範囲式forがある。

### switch
1\. 以下のように簡易文を記述することでswitch内のローカル変数を定義できる。
```go:
switch n := 1; n {
}
```
2\. case節に式を記述して比較することもできる。
3\. 1つのcaseの実行が終わるとswitchの処理も終わる。以下のように記述することでフォロースルーできる。
```go:
case 比較したい値:
    処理
    fallthrough
```
4\. 互換性のない型同士の比較はコンパイルエラーになる。
5\. interface型を使った型アサーションを学んだ。
#### 参考
[スターティングGo言語: Go1.6に対応](https://www.amazon.co.jp/%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0Go%E8%A8%80%E8%AA%9E-%E6%9D%BE%E5%B0%BE%E6%84%9B%E8%B3%80-ebook/dp/B01FH3KRTI/ref=sr_1_1?adgrpid=53639349256&dib=eyJ2IjoiMSJ9.BHh7QrjNux_7XwYafKioxZ7zpXMR4VOrEsIAZn2BGYK8jIn_rgZoKRlN9QKoKZOFA3swJCn_NXXazBbiCUbrizqhNxqWaWmjvDTLtZKx72K2vXBYsmkSsxxT4CJHGG73CUbnbgiel87xauS8XT4RPGOzjIdakJXb0Nd_oo_kJftdxq8gYfm5KyHLF6NREcjwGs738T_Whm2NhPmgfdbqeolPqxvYzzyHkGad31UzpqskXFfK7_g3WHGrCbySVyCLssgzefXSIwpD05FK6eAfnSxsmNfT_C2vflyK8ZEnQhI.ifnId7TVS8YJ4IxoQ-ihmipOVaoIAiY0wcNVyvFX3wc&dib_tag=se&hvadid=679022625319&hvdev=c&hvlocphy=1009228&hvnetw=g&hvqmt=e&hvrand=791236776647743631&hvtargid=kwd-334768382065&hydadcr=27264_14738595&jp-ad-ap=0&keywords=%E3%82%B9%E3%82%BF%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0go%E8%A8%80%E8%AA%9E&mcid=31f3aa7dc37e3eb5b7e96c2f685eaa46&qid=1740842280&sr=8-1/ "")

## セクション9：参照型
### スライス
1\. 数値型の引数を複数受取り、スライスとして扱う(sはスライスになる)。
```go:
func Sum(s ...int) int{
}
```
ただし、スライスを引数として渡したい場合は以下のように記述。
```go:
sl := []int{1, 2}
fmt.Println(Sum(sl...))
```

### スライスの宣言と操作
#### 参考
[Go slice ベストプラクティス](https://qiita.com/imoty/items/bb18fb50d526474d2d10/ "")

### スライス copy
~~参照型（スライス、map、チャネルも含めて）は参照渡しになる。~~
↓修正
#### そもそもスライスとは
まずGoには参照渡しという概念はなく、全てなにかしらの型の値渡しとなる。
**スライスを渡す**というのは、**構造体の内部実装のパラメータ（ポインタ、長さ、容量）を値渡しする**ということ。ポインタを含むスライス構造体が値渡しされるため、コピー先のスライスの要素を変更すると元のスライスの要素も変更することができる（参照的な振る舞いができる）。
```go:
func modifySlice(s []int) {
    s[0] = 100 
}

func main() {
    nums := []int{1, 2, 3}
    modifySlice(nums) // [1 2 3]
    fmt.Println(nums) // [100 2 3]
}
```
**参考**
こちらの内容とコメントを参考にしました。
[Go言語で理解する値渡しと参照渡し](https://qiita.com/atsutama/items/df7b8ff4ea2b4061d1ab/ "")
[【Goのやさしい記事】Goのポインタを5分で学ぼう](https://qiita.com/gold-kou/items/0d1585fb8d687061c890#:~:text=Go%E3%81%A7%E3%81%AF%E5%8F%82%E7%85%A7%E5%9E%8B%E3%81%AE,%E3%80%8C%E5%80%A4%E6%B8%A1%E3%81%97%E3%80%8D%E3%81%A8%E3%81%AA%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82/ "")
[Go Slices: usage and internals](https://go.dev/blog/slices-intro/ "")
#### copy
書き方
```go:
copy(値渡し先, 値渡し元)
```
~~copyを使って値渡しをする~~
↓修正（Goは基本値渡ししかないため、文章的に違和感がある。）
前述の通り、スライスの代入はポインタを含めたスライス構造体が値渡しされるため、異なるスライス変数でも同じデータを共有できる。
しかし、copyを使うことによって、元のスライスが参照している配列のデータを新しいスライスが参照する別の配列にコピーすることができ、独立した新しいスライスを作ることができる。
```go:
func main() {
    nums1 := []int{1, 2, 3, 4, 5}
    nums2 := make([]int, len(nums1))
    copy(nums2, nums1) 
    nums2[0] = 100

    fmt.Println("nums1:", nums1) // [1 2 3 4 5]
    fmt.Println("nums2:", nums2) // [100 2 3 4 5]
}
```

### map
mapの記述方法
```go:
map[キーの型]値の型{キー: 値}
```

### チャネル
1\. チャネルを学んだ。
2\. バッファサイズを超えるとデッドロック。
3\. データ構造はFIFO。

### チャネルとゴルーチン
1\. チャネルはゴルーチン間のデータの送受信のための機能
2\. チャネルをcloseすることでチャネルへのデータ送信が止まり、中身が受信され切るとゴルーチンが終了するという処理が可能になる。
```go:
close(チャネル名)
```
### チャネルselect
1\. select文を使って、case文で分岐された処理をランダムに実行しデッドロックを防ぐ。select文は設定されたcaseの中でどれかが実行可能なら処理を続行でき、どのcaseも実行できない場合にdefaultを実行する。
2\.Goの簡単な非同期処理を実装した。