【Part3】Go言語(golang)の基本とTips

環境

  • Windows 10
  • golang1.18
  • VSCode
  • Docker
masayan
masayan

以下のドキュメントは一読されることをおすすめします。

https://go.dev/doc/effective_go

本シリーズの記事で説明する内容

  1. きほんのき
  2. ファイル、クラス等の命名規則や慣習
  3. 環境構築
  4. モジュールのimport
  5. 変数定義と代入
  6. ポインタ
  7. 配列・スライス
  8. マップ
  9. 繰り返し
  10. 条件分岐
  11. 関数
  12. ジェネリクス
  13. クラスの作り方(正確にはクラスではない)
  14. インターフェース
  15. 単体テスト
  16. フォーマット
  17. その他Tips
masayan
masayan

本記事(part3)では、上記の9~13について説明します

繰り返し

for

  • 他のプログラム言語と同じ感覚で書ける
    for i := 0; i < 10; i++ {
        fmt.Println(i)
        // 0から9まで出力
    }

foreach (for … range)

  • foreach自体が存在しないので、forとrangeを組み合わせて実現する
  • 以下 i にはループ回数が、 lには配列の要素が順番に代入される
    lang_list := []string{"Go", "Python", "Ruby"}
    
    for i, l := range lang_list {
      fmt.Println(i, l)
      // 0 Go
      // 1 Python
      // 2 Ruby
    }

while(のようなもの)

  • while 文はないので for 文で条件式のみ書くとwhileみたいになる

    for i < 3 {
        fmt.Println(i)
        i++
    }
    
    // 0, 1, 2

条件分岐

if else if else

  • 他のプログラム言語と変わりなく書ける
    lang := "PHP"
    
    if lang == "Go" {
        fmt.Println("Goです")
    } else if lang == "PHP" {
        fmt.Println("PHPです")
    } else {
        fmt.Println("GoでもPHPでもない言語です")
    }

switch

  • 他のプログラム言語と変わりなく書ける
    lang := "Python"
    
    switch lang {
    case "Go":
        fmt.Println("Goです")
    case "PHP":
        fmt.Println("PHPです")
    case "Ruby":
        fmt.Println("Rubyです")
    default:
        fmt.Println("GoでもPHPでもRubyでもない言語です")
    }
  • caseに指定する値は複数書くことも可能
    case "Go", "Java":
      fmt.・・・・

関数

  • part1でも説明の通り、アクセス修飾子はなく、先頭が大文字ならpublic、小文字ならprivateになる
  • 引数と引数の型、返り値の型の記述が必要
    // 引数の数値を文字列に変換
    func toString(num int) string {
        return strconv.Itoa(num)
    }

ジェネリクス

  • 型パラメーター化できる
  • 以下の関数では、T型の配列と関数(T型の値を受け取ってV型の値を返す)を受け取り、V型の配列を返します
package util

import "fmt"

func ConvertType[T any, V any](array []T, f func(T) V) []V {

    list := []V{}

    for _, e := range array {
        somethingSting := f(e)
        fmt.Printf("%T\n", somethingSting)
        list = append(list, somethingSting)
    }

    return list
}
  • この関数に、数値の配列と以下のtoString関数を引数として渡すと数値(T)の配列をforで回してtoStringでstring型(V)に変換した配列が返ってきます
    package main
    
    import (
        "mymodule/util"
        "strconv"
    )
    
    func main() {
        intArray := []int{1, 2, 3, 4, 5}
    
        list := util.ConvertType(intArray, toString)
        println(list) // ["1", "2", "3", "4", "5"]
    }
    
    // 引数の数値を文字列に変換
    func toString(num int) string {
        return strconv.Itoa(num)
    }

クラス(Class)

  • goにクラスはないのでstructで代替可能
  • 例えば、recipe.goというクラスを作る場合は以下のような感じになる
  • まず、structでプロパティを定義する
  • コンストラクタをNewRecipe()として定義し、ポインタ型で生成した値を返す
    • コンストラクタの名称は慣習としてNewHoge()の形が用いられるのでその形にしている
  • 関数内で参照元を変更する必要があるものについては、レシーバーや返り値を適宜ポインタ型で定義する必要がある
    • init()やセッター
    • コンストラクタの返り値
  • 余談だが、レシーバを持つ関数をGoではメソッドと呼んでおり、ポインタ型でレシーバーが指定されているレシーバーはポインタレシーバーと呼ばれる
package recipe

type Recipe struct {
    id   int
    name string
}

func (r *Recipe) init(id int, name string) {
    r.id = id
    r.name = name
}

func NewRecipe(id int, name string) *Recipe 
    r := new(Recipe)
    r.init(id, name)
    return r
}


func (r Recipe) Id() int {
    return r.id
}

func (r Recipe) Name() string {
    return r.name
}

func (r *Recipe) SetName(name string) *Recipe {
    r.name = name
    return r
}

以上です。次回partでは14.~17.までの説明を行いたいと思います

    Go学習におすすめの書籍

    タイトルとURLをコピーしました