疑問点
- 「:=」はなんて読むんでしょうか?「コロンイコール」?「宣言代入」?
Tutorial
- A Tour of Go ブラウザでPlayground. 実践的でとてもわかりやすい。
メモ
変数の宣言と代入
page11-13.go
var a // 変数を宣言
a = 3 // 値を代入
var b = 1 // 変数を宣言して値を代入
c := 2 // 変数を宣言して値を代入。すでに定義済みの変数ではエラーになる
- :=が使えるのは関数内だけ。関数外のグローバル変数とかは必ずvarが必要。
定数
page15.go
const Pi = 3.14
const Dio = "URYYYYYYYYYY"
- 定数はconst(Constants)
- 定数も変数と同じくキャメル記法
for文
- for文の中でも := 使えます。
page17.go
for i := 0; i < 10; i++ {
fmt.Println(i*i)
}
- 省略もできます
page18.go
for sum := 1; sum < 1000; {
sum += sum
}
while文
- go言語のwhile文は
for 継続条件 { 処理 }
とforを使って記述する
page19.go
sum := 1
for sum < 1000 {
sum += sum
}
無限ループをfor文で表現する
- 継続条件を書かない場合は無限ループ。
for { 処理 }
とすっきり書ける
page20.go
for {
fmt.Println("LOOOOOP!")
}
if文
-
if 継続条件 { 処理 }
シンプル!
page21.go
if x < 0 {
fmt.Println("Minus")
}
short statement
- short statement(一時変数?)という仕組みがあり、if文の前処理を書くことができる。
- short statementはif文の中でのみ有効。else文の中でも使える。
- この変数(short statement)がif文にだけ関連しているということを明示できる。コードの見通しが良くなってめっちゃ便利!!
page23.go
if v := a + b; sum < limit {
return limit - v
} else {
return v - limit
}
構造体
- 構造体は
type Name struct { filds... }
- 構造体名は大文字始まりでキャメル記法
- 構造体の要素も大文字始まりでキャメル記法
page28.go
type Vertex struct {
X int
Y int
}
func main() {
v := Vertex{1, 2}
v.X = 4
fmt.Println(v.X)
}
- 初期値がない場合はゼロ初期化(zeroedと言うらしい)が保証される
page28-2.go
r = Vertex{X: 1} // Xは1で初期化されるし、何も書いてないYはデフォルトのゼロ初期化される
s = Vertex{} // X:0 and Y:0
- 構造体の要素へはドットアクセス
- 構造体と構造体のポインタは正確には違うものだけど、そこらへんコンパイラが空気読んでくれて、ドットアクセスすると構造体でもポインタでもフィールドが返ってくる。
- つまり、構造体か構造体のポインタか意識せずにドット使っときゃOK
page27-29.go
var t1 *T = new(T)
t2 := new(T)
fmt.Println(t1.X)
fmt.Println(t2.X)
配列
- 配列はSlices(スライス)と言うらしい。聞きなれない
- []T は、 T 型の配列
- 配列の長さを求めるにはlen()関数を使う
page30.go
p := []int{2, 3, 5, 7, 11, 13}
fmt.Printf(p[0])
fmt.Printf(len(p))
配列の範囲指定
- 配列の範囲指定をメソッド使わずにスッキリ書ける。イイネ!
page31.go
p := []int{2, 3, 5, 7, 11, 13}
fmt.Printf(p[2:4]) // index2から4まで
fmt.Printf(p[2:]) // 2以降すべて
fmt.Printf(p[:4]) // 4以前すべて
fmt.Printf(p[x:x+2]) // xから3つ
配列でfor文を回す
for i, obj := range array { 処理 }
- 「forループ文のrangeフォーム」と言うらしい
- 多言語で「拡張for文」「高速列挙」とか言われてるやつ
page34.go
var array = []int{1, 2, 4, 8, 16, 32, 64, 128}
for i, v := range array {
fmt.Printf(i, v)
}
- iが不要な場合は、_とすると破棄される。
- 基本_にして、indexを使う時だけiにするとシンプルでGood. Swiftでも同じですね。
page35.go
for _, v := range array {
fmt.Printf(v)
}
Maps (KeyValue形式)
make(map[keyの型]valueの型)
- Mapsの生成にはnewではなくmake()関数を使う
- 多言語で「Map」「Dictionary」とか呼ばれてるやつ
page38.go
var stands = map[string]string {
"ジョセフ・ジョースター" : "ハーミット・パープル",
"トリッシュ・ウナ" : "スパイス・ガールズ",
}
Mapsの追加、参照、削除
- 要素の削除に関数を使うのはちょっと野暮ったい気もする
page40.go
var stands = make(map[string]string){} // 空のMapsを生成
stands["仗助"]="クレイジー・ダイヤモンド" // 要素の追加
fmt.Println(stands["仗助"]) // 要素の参照
delete(stands, "仗助") // 要素の削除
課題
- 地味に分かりにくいけど、引数の文字列を単語で分割して、各単語の出た回数を求めてMapsで返却するというもの
page41.go
func WordCount(s string) map[string]int {
words := make(map[string]int)
for _, word := range strings.Fields(s) {
words[word] += 1
}
return words
}
クロージャ
- goの関数はclosureらしい
- もちろん関数(closule)を変数に入れて受け渡しできる
- サンプルプログラムはわかりにくくて、以下のサイトのが参考になった
- クロージャ(Closure)が難しい | 30歳からのプログラミング入門日記
Switch
- switch caseは、上から下へcaseを評価する
- caseの条件が一致すれば、そこで停止してbreak。breakさせたくなければ
fallthrough
を書く - switch文にも前処理書ける
page46.go
switch os := runtime.GOOS; os {
case "darwin":
fmt.Println("OS X.")
case "linux":
fmt.Println("Linux.")
default:
fmt.Printf("%s.", os)
}
- 一般的に
switch 変数名 { case 変数が取りうる値: 処理 }
と書くと思うんだけど、変数名を書かなかった場合、caseには条件式が書け、caseの条件式を上から順に評価する。 -
switch {case a < 100: 処理 case b == 3: 処理}
とか。 - つまり、長い長い
if-then-else
をswitch caseで書ける…らしいんだけど、長いif-then-elseの代わりにswitch文使うのって一般的なのかな? if文とそんなに見た目も変わらない気もする。
page47.go
t := time.Now()
switch {
case t.Hour() < 12:
fmt.Println("Good morning!")
case t.Hour() < 17:
fmt.Println("Good afternoon.")
default:
fmt.Println("Good evening.")
}
その他
- ご指摘大歓迎です! 気になる点がありましたら気軽にコメントください。 よろしくおねがいします!