環境
- Windows 10
- golang1.18
- VSCode
- Docker

masayan
以下のドキュメントは一読されることをおすすめします。
https://go.dev/doc/effective_go
本シリーズの記事で説明する内容
- きほんのき
- ファイル、クラス等の命名規則や慣習
- 環境構築
- モジュールのimport
- 変数定義と代入
- ポインタ
- 配列・スライス
- マップ
- 繰り返し
- 条件分岐
- 関数
- ジェネリクス
- クラスの作り方(正確にはクラスではない)
- インターフェース
- 単体テスト
- フォーマット
- その他Tips

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.までの説明を行いたいと思います