【GO】Golangの勉強を始めたから殴り書きのメモ~その1
A tour of Go を基にメモ。 誤字脱字はすみません。 いつか綺麗に書く。多分。 tour.golang.org
- Goのプログラムは、パッケージ( package )で構成される。
- mainのmain()が実行される 次の二つは同じ
import "fmt" import "math/rand"
import ( "fmt" "math/rand" )
- 最初の文字が大文字で始まる名前は、外部のパッケージから参照できるエクスポート(公開)された名前( exported name )です。
=> 大文字始まりにすれば、外部パッケージから参照できる。
関数の定義
- 普通にかく
// func 関数名(引数a aの型, 引数b bの型) int { ... } func add(x int, y int, z int) int { return x + y + z }
- 引数の型が同じなら省略できる
// 上のやつと同じ func add(x, y, z int) int { return x + y + z }
- 二つ戻り値もてるよ
func swap(x, y string) (string, string) { return y, x } func main() { // 関数の戻り値を代入 a, b := swap("World", "Hellow") println(a, b) // Hellow World }
- 戻り値に名前つけられるよ
// xとyが戻り値。これも戻り値の型が同じだと省略できる。 // 短い関数だけで使おう。可読性が落ちるんだってさ。 func super() (x, y string) { x = "Java" y = "おじさん" return // naked return って言うらしい } func main() { fmt.Println(super()) // Java おじさん }
変数の定義
- 普通に宣言
package main import "fmt" // パッケージ内で宣言できるよ。 // 変数も同じ型なら省略できるんだって。 var c, python, java bool func main() { // 関数内でも宣言できるよ。 var i int // 宣言だけした場合、intは0, boolはfalseが入るよ。 fmt.Println(i, c, python, java) // 0 false false false }
- 宣言して代入
package main import "fmt" // 宣言して代入 var i, j int = 1, 2 func main() { // 関数内でも宣言して代入 var c, python, java = true, false, "no!" fmt.Println(i, j, c, python, java) // 1 2 true false no! }
- 省略した宣言して代入
package main import "fmt" // 関数の外では省略した書き方はできない func main() { // 普通の宣言して代入 var i, j int = 1, 2 // 省略した書き方 k := 3 c, python, java := true, false, "no!" fmt.Println(i, j, k, c, python, java) //1 2 3 true false no! }
- 変数のゼロ値 宣言したけど初期値入れないとゼロ値が与えられる。
数値型(int,floatなど): 0 bool型: false string型: "" (空文字列( empty string ))
- 型の変換 T(v)・・・vをT型に変換する時
var i int = 42 // int -> float64 var f float64 = float64(i) // float64 -> unit var u uint = uint(f)
// 上のやつの省略系 i := 42 f := float64(i) u := uint(f)
定数の定義
- 普通に定義
package main import "fmt" // 関数外でも定義できるよ // :=は使えない const Pi = 3.14 func main() { // 関数内でも:=は使えない const World = "世界" fmt.Println("Hello", World) fmt.Println("Happy", Pi, "Day") const Truth = true fmt.Println("Go rules?", Truth) }
For文
- 一般的な形
func main() { sum := 0 // iが10以上になったら終わり // iの初期値は0 // 一周したらiをインクリメント(後処理ステートメント) for i := 0; i < 10; i++ { sum += i } fmt.Println(sum) // 45 }
- 初期化とかなくてもええんやで
func main() { sum := 1 // 初期化と後処理ステートメントはなくてもいい for ; sum < 1000; { sum += sum } fmt.Println(sum) }
// 初期化と後処理ステートメントないならセミコロンもいらん func main() { sum := 1 for sum < 1000 { sum += sum } fmt.Println(sum) }
if文
- 一般的なif
func sqrt(x float64) string { // ()はいらない if x < 0 { return sqrt(-x) + "i" } return fmt.Sprint(math.Sqrt(x)) } func main() { fmt.Println(sqrt(2), sqrt(-4)) }
- 簡単なステートメントを書ける
func pow(x, n, lim float64) float64 { // 変数vを宣言できるよ // このifの中でしか変数vは使えないよ if v := math.Pow(x, n); v < lim { return v } return lim }
- if-else
func pow(x, n, lim float64) float64 { if v := math.Pow(x, n); v < lim { return v // elseも使えるね } else { fmt.Printf("%g >= %g\n", v, lim) } // can't use v here, though return lim }
switch文
package main import ( "fmt" "runtime" ) func main() { fmt.Print("Go runs on ") // if文と同じように変数osを定義できる switch os := runtime.GOOS; os { case "darwin": fmt.Println("OS X.") // breakはなくても良いのだよ case "linux": fmt.Println("Linux.") default: // freebsd, openbsd, // plan9, windows... fmt.Printf("%s.", os) } }
func main() { t := time.Now() // こんな書き方もできる。 // switch true {...} と同じ switch { case t.Hour() < 12: fmt.Println("Good morning!") case t.Hour() < 17: fmt.Println("Good afternoon.") default: fmt.Println("Good evening.") } }
Defer(遅延させる)
package main import "fmt" func main() { // 引数の評価はされるけど、呼び出し元の関数がreturnするまで延期 defer fmt.Println("world") fmt.Println("hello") } // 出力 // hello // world ★ helloよりも後に実行される
- 複数のDefer
package main import "fmt" func main() { fmt.Println("counting") for i := 0; i < 10; i++ { // たくさんdeferする // 先入れ後出し方式 // 箱の中に順番にモノを入れていって、上から順番に出す感じです defer fmt.Println(i) } fmt.Println("done") } /* 出力 counting done 9 8 7 6 5 4 3 2 1 0*/
続く。。。