Go 言語速攻チェック表 (Cheat Sheet)
Go(別名 Golang)は、Google の Robert Griesemer、Rob Pike、および Ken Thompson によって開発された、静的型付けのコンパイル言語です。Go 言語の構文は C 言語に似ていますが、メモリ安全性、GC(ガベージコレクション)、構造的型付け、および CSP スタイルの並行計算などの機能を備えています。
Hello world
package main
import "fmt"
func main() {
message := greetMe("world")
fmt.Println(message)
}
func greetMe(name string) (string) {
return "Hello, " + name + "!"
}
$ go build変数
変数宣言
var msg string
msg = "Hello"略記法
msg := "Hello"定数
const Phi = 1.618定数は、文字、文字列、ブール値、または数値にすることができます。
基本型
文字列 (Strings)
str := "Hello"
str := `複数行の
文字列`文字列の型は string です。
数値
代表的な型
num := 3 // int
num := 3. // float64
num := 3 + 4i // complex128
num := byte('a') // byte (uint8 のエイリアス)その他の型
var u uint = 7 // uint (符号なし)
var p float32 = 22.7 // 32ビット浮動小数点数ポインタ
func main () {
b := *getPointer()
fmt.Println("Value is", b)
}
func getPointer () (myPointer *int) {
a := 234
return &a
}ポインタは、変数のメモリ位置を指します。Go は完全なガベージコレクション機能を備えています。
配列 (Arrays)
// var numbers [5]int
numbers := [...]int{0, 0, 0, 0, 0}配列のサイズは固定です。
スライス (Slices)
slice := []int{2, 3, 4}
slice := []byte("Hello")配列とは異なり、スライスは動的なサイズを持ちます。
制御構文
条件分岐 (If)
if day == "sunday" || day == "saturday" {
rest()
} else if day == "monday" && isTired() {
groan()
} else {
work()
}if 内のステートメント
if _, err := getResult(); err != nil {
fmt.Println("Uh oh")
}if 文は、条件式の前に簡単なステートメントを実行できます。
Switch
switch day {
case "sunday":
// デフォルトでは "fall through" しません!
fallthrough
case "saturday":
rest()
default:
work()
}関数
ラムダ (関数の値)
myfunc := func() bool {
return x > 10000
}関数は第一級オブジェクトです。
複数の戻り値
a, b := getMessage()
func getMessage() (a string, b string) {
return "Hello", "World"
}名前付き戻り値
func split(sum int) (x, y int) {
x := sum * 4 / 9
y := sum - x
return
}戻り値の名前に変数を宣言することで、return(引数なし)はそれらの名前の変数を返します。
パッケージ
インポート
import "fmt"
import "math/rand"
import (
"fmt" // fmt.Println を提供
"math/rand" // rand.Intn を提供
)どちらも同じです。
エイリアス
import r "math/rand"
r.Intn()公開名 (Exported names)
func Hello () {
···
}公開名は、大文字で始めます。
パッケージ宣言
package hello各パッケージファイルは package から始まる必要があります。
並行性 (Concurrency)
ゴルーチン (Goroutines)
func main() {
// チャネルの作成
ch := make(chan string)
// 並行ルーチンの開始
go push("Moe", ch)
go push("Larry", ch)
go push("Curly", ch)
// 3 つの結果を読み取る
// (ゴルーチンは並行であるため、
// 順序は保証されません!)
fmt.Println(<-ch, <-ch, <-ch)
}
func push(name string, ch chan string) {
msg := "Hey, " + name
ch <- msg
}チャネルは、ゴルーチン間で使用される並行セーフな通信オブジェクトです。
バッファ付きチャネル
ch := make(chan int, 2)
ch <- 1
ch <- 2
ch <- 3
// fatal error:
// all goroutines are asleep - deadlock!バッファ付きチャネルは、保持できるメッセージの数を制限します。
チャネルのクローズ
チャネルをクローズする
ch <- 1
ch <- 2
ch <- 3
close(ch)クローズされるまでチャネルを反復処理する
for i := range ch {
···
}ok == false の場合はクローズされています
v, ok := <- ch遅延実行 (Defer)
Defer
func main() {
defer fmt.Println("Done")
fmt.Println("Working...")
}関数の実行を、それを囲む関数が終了するまで遅延させます。引数は即座に評価されますが、関数呼び出しは最後まで実行されません。
ラムダを使用した Defer
func main() {
defer func() {
fmt.Println("Done")
}()
fmt.Println("Working...")
}遅延ブロックにはラムダ(匿名関数)が適しています。
構造体 (Structs)
定義
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X, v.Y)
}リテラル
v := Vertex{X: 1, Y: 2}
// フィールド名を省略可能
v := Vertex{1, 2}
// Y は暗黙的
v := Vertex{X: 1}フィールド名を指定することもできます。
構造体へのポインタ
v := &Vertex{1, 2}
v.X = 2v がポインタの場合、v.X と (*v).X は同じです。
メソッド
レシーバ
type Vertex struct {
X, Y float64
}
func (v Vertex) Abs() float64 {
return math.Sqrt(v.X * v.X + v.Y * v.Y)
}
v := Vertex{1, 2}
v.Abs()クラスはありませんが、レシーバを使用して型に関数を定義できます。
ポインタレシーバ
func (v *Vertex) Scale(f float64) {
v.X = v.X * f
v.Y = v.Y * f
}
v := Vertex{6, 12}
v.Scale(0.5)
// `v` が更新される