Golang学習メモ Week1 

12/5改稿
リレーを回すために当社のアドベントカレンダーに追加しました。 
一部表現等も修正


## この記事を執筆した経緯 

業務で扱う言語(現職ではJava/VB.NET)以外を完全に触らなくなって何年だ？とふと思ったのでプログラミングの楽しさを思い出すために触ったことのない言語で遊んでみようと思いたった。競プロとかにも興味があるので最終目標は競プロで良い成績を残せるレベルまでスキルを身に着けたい。

アウトプットでの知識の定着と、私と同じように業務で書くコードに飽きがきてGoを触りたくなった人が後追いしやすくなるように記事を執筆。なお、私の業務量と他の趣味と資格勉強等の兼合いもあるため、どの程度続くかは今の所わからない。

記事内に書くと視認性が落ちる長文コードなんかは下記のGithubにPushしていく予定。
・Github(準備中)

#### 24年12月目標
・最低週1の投稿
・Paizaスキルチェック Aランク満点

#### 勉強用記事・サイト(順次追加)
参考記事内で照会されているリンクと重複している部分がありますが、私的なメモなのでご容赦ください。

・[Goの初心者が見ると幸せになれる場所　#golang](https://qiita.com/tenntenn/items/0e33a4959250d1a55045)
・[A Tour of Go](https://go.dev/tour/welcome/1)
・[Paizaラーニング | プログラミングスキルチェック](https://paiza.jp/challenges)

## 以下学習メモ
### 1. Go 変数宣言
変数宣言はVBライクだが業務のメインはJavaなので少し戸惑う。
Goで実際に変数定義をするときは 1 or 3 で書くことになるとは思う。

~~~test.java
int hoge = 100;
~~~
~~~test.vb
Dim hoge As String
hoge = "ABC"
Dim hoge As String: str = "ABC"
~~~
~~~test.go
var hoge int = 100 // 1.型宣言有
var hoge2 = 100    // 2.型宣言省略
hoge3 := 100       // 3.型宣言どころかvarも省略
var hoge4 [3]int   // 4.配列宣言
~~~

[Goの宣言構文](https://go.dev/blog/declaration-syntax)
[Go-lang:変数宣言と初期化](https://emucyo.hatenadiary.org/entry/20110423/1303517255)

### 2. Go 標準入出力
標準パッケージを使って実施するのは割と良くある仕様だと思う。
Println関数に複数値を渡すと空白区切りを挟み、1行で出力される仕様がある。
これは素直に面白い。~~使いどころある？~~
標準入力は業務で使うことが全くなかったので、ここら辺の勉強は学生時代以来でなつかしさを覚えた。

~~~main1.go
package main
import "fmt" // パッケージインポート
func main(){
    var str string   // 変数定義
    fmt.Scan(&str)   // 標準入力を変数格納 1行だけ
    
    fmt.Println(str) // 標準出力
    fmt.Println("1", "2", "4") // '1 2 4'が出力される
}
~~~

大量のデータの入力となる場合は`fmt.Scan`より`bufio.NewScanner(ost.Stdin)`の方が処理速度は良くなるらしい。競プロを将来的にやりたいのでbufioを使うやり方を覚えておきたい。

~~~main2.go
package main
import (
    "bufio"
    "fmt"
    "os"
)
func main(){
    scanner := bufio.NewScanner(os.Stdin)
    scanner.Scan()
    var str string = scanner.Text()
}
~~~

[【競プロ】Goの標準入力チートシート](https://zenn.dev/pikarich/articles/8f1c7fe4d04e93)
[Go言語 標準入力 【自分用まとめ】](https://zenn.dev/rabbit_penguin0/articles/4306dc025d2715)
[【備忘】Go 言語の標準入力の基本的なこと](https://qiita.com/t-yama-3/items/99ecf0466e5e0f080815)

### 3. Go 真偽判定
私はif-elseを書く時はJavaサンプルのようにブロック単位の処理をわかりやすくするようにしたり単純な分岐だと`{}`を省くのだが、Goだとこれはエラーになり許されない。ぴえんである。
またOR/AND条件式で1行が長くなって見難いため、見易くしようと改行するとビルドエラーになった。

代わりに条件式の`()`は省略できる。
~~これは省略するとややこしくなるだけでマイナスではないだろうか...~~

~~~main.java
// comment
if(str == "hoge") {
    fmt.Println("YES")
} 
// other
else {
    fmt.Println("NO")
}

// パターン2
if (str == "hoge") fmt.Println("YES")  
else fmt.Println("NO")  
~~~
~~~main.go
if (str == "hoge"){
  fmt.Println("YES")    
} else{
  fmt.Println("NO")    
} 

// 条件式のカッコは省略できる。
if n <= 100 {
    fmt.Println("YES")
} else {
    fmt.Println("NO")    
}

// 複数条件式を書くときは1行で。これはOK
if a == b && a == c {
}
// こっちだとOUT
if a == b 
   && a == c {
}
~~~

### 4. Go ループ処理
ループ用変数の宣言が省略系でかけるところ以外は特筆すべきことがない？というのがファーストインプレッション。なおwhileは無いし、無限ループも強制true式を使わないのでそうでもなかった。
ただし、式書くときの`()`省略必須というものは他言語と使い分けて書いているとそのうち間違えそう。

~~~main.go
// 普通のfor
for i := 0; i < 5; i++ {
    // todo
}

// whileの代替もfor
for i < 10 {
    // todo
}

// 無限ループは凄い簡素
for {
    // todo 
}

// 他言語と同じ感じで書いたらエラーになった
for (i := 0; i < x; i++) {
}
~~~

[Go言語(golang)のループ for, for..range, foreach, while](https://golang.hateblo.jp/entry/2019/10/07/171630)


### Week1所感
使っていないパッケージ・変数がある場合、ビルドエラーが発生するという仕様はかなり良い仕様だと思う。
秘伝の継ぎ足しプロジェクトだと使わなくなったパッケージ等が放置され気味なこともあるので、障害を起こす可能性を少しでも減らそうという仕様はプロジェクトに採用する会社が最近多いのも納得。

絶対これだけじゃないけれどまだ言語仕様把握しきれていないので、採用理由としての強みを理解できるようにしたい。

if-elseのブロック周りは普通に困った。かなり可読性が悪く感じる。
勉強を進めていけば何か良い方法が出てくるか？

とりあえずPaizaのDランクの基礎メニューは上記の内容を抑えてコンプ
その言語の基本的な文法さえ把握すれば解ける難易度なので丁度良い。
Cランク以降はメニューが多すぎたり、チケット消費等が必須で回復時間を待つのも多いから基本的な理解ができるメニューを優先していこうと思う。

![go1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796391/e1e1da2f-0118-13e3-f6bf-d378d7be850d.png)


それでは今回はこの辺で。最後まで読んでくださり感謝。