# Golang Development SDGs(for beginners) **インストール** ```console $ echo `uname`_`arch` # OS と Arch を確認 Linux_amd64 $ curl -OL https://go.dev/dl/go1.17.5.linux-amd64.tar.gz $ sudo rm -rf /usr/local/go && sudo tar -C /usr/local -xzf go1.17.5.linux-amd64.tar.gz $ echo 'export PATH=$PATH:/usr/local/go/bin' >> ~/.profile $ exec $SHELL -l $ go version go version go1.17.5 linux/amd64 ``` **SDGs で学ぶ Go 言語** ## 1. snake_case や Nazo_Snake_Case をやめよう 変数名: camelCase, PascalCase private/public: camelCase, PascalCase ファイル名: snake_case 例) `hoge_test.go` ## 2. 変数のスコープは狭くしよう ```go= sum := 0 for i := 0; i < n; i++ { // sum := 0 for j := 0; j < n; j++ { sum += a[j] } fmt.Println(sum) } ``` sum はスコープが広すぎる ## 3. スライスの iteration は for-range を使おう ```go= a := []int{1, 2, 3} for i := 0; i < len(a); i++ { fmt.Println(a[i]) } for i, elem := range a { fmt.Println(elem) // a[i]++ } ``` ## 4. スライスのスライスはスライスで行おう ```go= a := []int{1, 2, 3, 4} b := []int{} c := []int{} for i := 0; i < 2; i++ { b = append(b, a[i]) } for i := 0; i < 2; i++ { c = append(c, a[i]) } b = a[:2] c = a[2:] ``` ## 5. 構造体はコンストラクタを作ろう ```go= type Student struct { Name string Number int } func NewStudent(name string, num int) Student { return Student { Name: name, Number: num, } } stu := Student { Name: "かじはらかじ", Number: 70010000, } ``` ## 6. 構造体はメソッドで操作しよう ```go= func Whoami(stu Student) { fmt.Println(stu.Name) } Whoami(stu) // これを使おう func(stu *Student) Whoami() { fmt.Println(stu.Name) } stu.Whoami() ``` **Break time** これを Go でとこう https://atcoder.jp/contests/abc232/tasks/abc232_b 入力 ```go= var ( s string t string ) fmt.Scan(&s, &t) set := map[int]struct{}{} for i := 0; i < len(s); i++ { d := int(t[i]) - int(s[i]) if d < 0 { d += 26 } set[d] = struct{}{} } fmt.Println(func() string { if len(set) == 1 { return "Yes" } else { return "No" } }()) ``` ## 7. エラーハンドリングはしっかりしよう ```go= package main import "strconv" func main() { num1, _ := strconv.Atoi("123") num2, err := strconv.Atoi("abc") if err != nil { log.Println(err) return } } ``` ## 9. `*os.File` や `io.ReadCloser` は必ず読んで Close しよう ```go= fp, err := os.Open("hoge.txt") if err != nil { log.Println(err) return } // なんかの処理 fp.Close() ``` ## 10. defer を使おう defer ... スコープが終わった時に実行してくれるやつ ```go= fp, err := os.Open("hoge.txt") if err != nil { log.Println(err) return } defer fp.Close() // なんかの処理 ``` ## 11. 関数化をしよう ```go= func MyFunc(arg0 int, arg1 string) int { return arg0 } func MyAtoi(s string) (int, error) { x := 0 err := nil return (x, err) // だめ return x, err // いいよ } ``` **break time** これをとこう https://atcoder.jp/contests/abc217/tasks/abc217_c ```rust= input! { n: usize, p: [i32; n] } let mut q = vec![0; n]; for (i, &elem) in p.iter().enumerate() { q[elem as usize - 1] = i + 1 } println!( "{}", q.iter() .map(|x| x.to_string()) .collect::<Vec<_>>() .join(" ") ); ``` ## 12. パッケージ単位でモジュール化をしよう ```console $ mkdir gopher-project $ cd gopher-project $ go mod init gopher-project ``` ```console $ ls -T project ├──  go.mod ├──  main.go └──  mymath └──  prime.go ``` mymath/prime.go ```go= package mymath // O(1) func IsPrime(x int) bool { return !(x % 2 == 0) } ``` ## 12.5 テスト mymath/prime_test.go ```go= package mymath import "testing" func TestIsPrime(t *testing.T) { if !IsPrime(2) { t.Error(e) } } ``` ## 13. 引数では構造体はなるべくポインタで受け取ろう ## 14. gofmt でフォーマットを整えよう go の基礎はここまで --- ## 16. クソデカ commit はやめよう ## 17. commit message にポエムを書くのはやめよう これが結構おすすめ https://qiita.com/numanomanu/items/45dd285b286a1f7280ed ## 18. main に push するのはやめよう ## 19. Pull Request で何をどうしたのか説明をしっかり書こう ## 20. コードレビューでいじめるのはやめよう