Golang学習メモ Week1 day2

## 前回のあらすじ
思い立ったが吉日の精神で30～60分くらいと思いながら半日くらいGoで遊んでいた。
プログラミングを初めて触った学生時代を思い出して楽しかったので勉強したことを記事投稿してみた。

## 今週の学習内容
続いた。
ウィークリーにする予定ではあったが週1回更新とは言っていないのでDay2。
思ったより自分には何かを学ぼうとするモチベーションはあったのかも。
~~なお会社から業務命令が出ている資格取得は今のところノータッチ。ちょっとヤバいかも~~

### 1. Go 未使用変数のエラー
宣言したのに利用していない変数があるとエラーになる。~~初回の記事に何故これが無いのか~~
ちなみに`_`変数であれば未使用でもエラーにはならない。
なお`_`変数は省略系の暗黙の型変換宣言はエラーになる。~~用途的に使うことはなさそう~~
~~~
Main.go:5:5: hoge declared but not used
~~~
~~~main.go
var _ string = "hoge"
_ = "fuga"

// "no new variables on left side of :=" というエラーを返す
_ := "piyo"
~~~
[golangで「declared and not used」というエラーが出たときの原因と対処法](https://note.com/webdrawer/n/n9891afb9c14b)

### 2. Go 配列の初期化
省略形もvar宣言のどちらでもできる。
配列の長さを`...`とすることで可変できるっぽい
ただvar宣言を使う場合、配列の初期化は通常のvar宣言 `(例)var str string = "hoge"` とは微妙に違うので注意したい。~~配列初期化なんてほぼ使わないとは思うが~~

~~~main.go
// 省略系
testArray1 := [5]int{10, 20, 30, 40, 50}
testArray2 := [...]int{10, 20, 30, 40, 50}
// var宣言
var testArray3 = [3]int{10, 20, 30}
var testArray4 = [...]int{10, 20, 30}
// 配列じゃない変数宣言のように初期化しようするとエラー
var testArray5 [3]int = {10, 20, 30}
~~~

[Go言語 配列](https://recursionist.io/learn/languages/go/complex/array)

### 3. Go 配列のループ処理
他言語でよくあるものだとlength()で上限を指定したりforeachを使ったりする。
Goにはforeachは無い代わりに`for...range`構文がある。`for...range`構文はループ回数の取得だけはなく、中身の値も直接取得できる。これは便利。
直接値を取得できるということは、`array[i]`のようにループ回数を使うことがないので、上述した`_`変数を使うのがよさそう。

~~~main.go
// length関数利用
for i :=0; i< len(array); i++ {
    // todo
}

// for...range 
// ループ回数だけ取得
for i := range ary {
    // todo
}
// iにループ回数, valueに配列の値が入る
for i, value := range ary {
    // todo
}
// for...range使うなら恐らくこれ
for _, value := range ary {
    // todo
}
~~~
[Go言語(golang)のループ for, for..range, foreach, while](https://golang.hateblo.jp/entry/2019/10/07/171630)

### 4. Go 文字列分割
Javaのように型に備え付けられておらず、パッケージをインポートしての呼び出し。
Go言語における基本的な処理は大体標準パッケージを呼び出して使う感じになるのかな？

~~~main.java
String[] arr = str.split(",");
~~~
~~~main.go
import (
    ...
    "strings"
)
func main(){
    arr := strings.Split(str, ",")
}
~~~

[【Go】strings パッケージ関数まとめ](https://zenn.dev/kou_pg_0131/articles/go-strings-functions)

### 5. Go 文字列変換
strconvパッケージが文字列型⇔他の型を一律で管理している模様。
float変換に関してはfloat32は使うことが殆ど無いだろうし第二引数は64固定で良いはず

~~~main.go
// string to int
i, err := strconv.Atoi(str)
// string to float64
f, err := strconv.ParseFloat(str, 64)

// int to string
s := strconv.Itoa(i)
~~~
[strconv](https://pkg.go.dev/strconv@go1.19)
[【Golang】文字列と数値の変換(strconv)](https://qiita.com/mei4n/items/308e75092e2a058d75f2)

### 6. Go 標準入出力 複数の変数
Scan,Printどちらの関数も文字列のフォーマットを指定してやれば1行で複数の変数を処理できる。これは他言語でもあった気はする。遥か昔の学生時代にC言語でやった記憶があるぞ。

~~~main.go
var a,b int
fmt.Scanf("%d %d", &a, &b)
fmt.Printf("%d,%d", a, b)
~~~
[【競プロ】Goの標準入力チートシート](https://zenn.dev/pikarich/articles/8f1c7fe4d04e93)

### 7. Go 数値カンマ区切り
JavaでいうとこのNumberFormatみたいな標準パッケージは調べても出てこなかった。代わりに準標準パッケージを使うやり方がヒットした。
標準パッケージのみでやるには力業しかなさそう。
力業手法の中でやっている文字列の抜き出しについては項目8へ。

~~~main1.go
import (
	"golang.org/x/text/language"
	"golang.org/x/text/message"
    
    "dustin/go-humanize"
)
func main(){
    // x/text package 
    var n int = 1000
 	p := message.NewPrinter(language.Japanese)
	p.Printf("%d\n", n) // 1,000

    // humanize package
    c := humanize.Comma(n) 
    fmt.Println(c) // 1,000
}
~~~
~~~main2.go
length := len(str)
if length <= 3 {
    comma = str
} else {
    // 最初のカンマ区切り
    comma = str[0:length%3]

    // 残りの部分を3桁ごとに追加
    for i := length % 3; i < length; i += 3 {
        if i > 0 {
            comma += ","
    }
    comma += str[i:i+3]
}
~~~


[【Golang】数値をコンマ区切りで出力する【1000桁単位のカンマ区切りフォーマット出力】](https://qiita.com/KEINOS/items/d8c14f0951ec890ae3ff)
[dustin/go-humanizeでカンマ区切り](https://kentama.hatenablog.com/entry/2018/12/31/153613)

### 8. Go 文字列抜き出し
Javaにおけるsubstring関数のような挙動が文字列変数のindexを直接指定するだけで可能である。
文字の抜き出しをシンプルにかけるのは中々良い仕様だと思う。

~~~main.go
str := "123456789"
fmt.Println(str[0:3]) // 123 を出力
~~~

[[Golang] 文字列操作サンプル](https://qiita.com/tchnkmr/items/b3d0b884db8d7d91fb1b)

### 9. Go 有効桁数
C言語を思い出すフォーマット指定
Sprintf関数はフォーマット通りの文字列を作ってくれる。
~~~main.go
fl := 3.14
fmt.Sprintf("%.3f", fl) // 3.140を出力
~~~

### 10. Go Switch文
case一致で自動breakしてくれるのはコードを短縮できてよい機能。癖でbreakを書いてしまうのはご愛嬌
~~~main.go
switch num{
    case 1:
        // hoge
    case 2:
        // fuga
    default:
        // piyo
}
~~~

### Week1 day2 所感

無駄に長くなりすぎると私がメモを追いきれなくなってしまうのでこの辺で

Paizaの標準出力クエストは学生時代やった出力芸を思い出して懐かしくなりました
![go2.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3796391/bc5a516a-278b-abef-4754-2177bd893325.png)