Go 文法
https://gyazo.com/6cbe54e460e4e198f640e4609e5ddfd2
◎変数と定数
変数定義(型推論があるので型は省略できる)
code:main.go
func main() {
var n int = 100
var n = 100
n := 100 // (関数内ではvarを省略できる)
}
明示的な初期化をしなくてもゼロ値が設定されるから使える
ex)0、""、false、nil
ルーン(rune)1Byte、Cで言うchar型
複素数(complex)1+4iみたいに定義
定数定義
code:go
const n int = 100
const m = 100 // (型のない定数)
printf("%T", n)とするとnの型が分かる
◎演算子
論理演算
論理和 or( || )
論理積 and( && )
否定 not( ! )
アドレス演算
ポインタを取得 &a
ポインタが指す値を取得 *a
チャネル演算
チャネルへの送受信 <-
◎制御構文
条件分岐 if
()がいらない
code:main.go
i := 2
if i % 2 == 0 {
println("偶数")
} else {
println("奇数")
}
条件分岐 switch
breakがいらない
caseに式が使える
caseをまたぐときはfallthroughを使う
code:main.go
i := 2
switch i {
case 1:
println("1")
case 2:
println("2")
case 3:
println("3")
default:
println("4以上")
}
繰り返し for
繰り返し処理はこれしかない
()をつけてはいけない
code:main.go
for i := 1; i <= 5; i++ {
println(i)
}
break LOOP とするとLOOPを定義したところから抜ける
gotoも存在する
code:main.go
var i int
LOOP:
for {
println(i)
if i%7 == 4 {
break LOOP
}
i++
}
◎型
コンポジット型
構造体 型の異なるデータ型を集めたデータ型
配列 同じ型のデータを集めて並べたデータ型
スライス 配列の一部を切り出したデータ型
マップ キーと値をマッピングさせたデータ型
構造体
code:main.go
person := struct {
name string
age int
}{name: "Kohei", age: 22}
fmt.Println(person) // {Kohei 22}
fmt.Println(person.age) // 22
配列
最初に宣言した配列のサイズを変えることができない
code:main.go
// ゼロ値で初期化
// 配列リテラルで初期化
var ns1 = 5int{10, 20, 30, 40, 50} // 要素数を値から推論
ns2 := ...int{1, 2, 3, 4, 5} // 指定した場所以外はゼロ値で初期化される
ns3 := ...int{1: 10, 3: 30} fmt.Println(len(ns3)) // 4
スライス
スライスはベースとなる配列が存在している
初期化の時に要素数を指定する必要はない
code:main.go
// ゼロ値はnil
var ns1 []int
// 長さと容量を指定して初期化
ns1 = make([]int, 3, 10)
// スライスリテラルで初期化
// 要素数は指定しなくてよい
// 自動で配列は作られる
var ns2 = []int{10, 20, 30, 40, 50}
// 5番目が50、10番目が100で他が0の要素数11のスライス
ns3 := []int{5: 50, 10: 100}
fmt.Println(ns1) // 0 0 0 appendの挙動
容量が足りる場合
新しい要素をコピーし、lenを更新する
容量が足りない場合
元のおよそ2倍の容量の配列を確保し直し、配列へのポインタを貼り直す
元の配列から要素をコピーし。新しい要素もコピーする
lenとcapを更新する
code:main.go
var ns = []int{10, 20, 30, 40, 50}
fmt.Println(len(ns)) // 長さ 5
fmt.Println(cap(ns)) // 容量 5
ns = append(ns, 60, 70)
fmt.Println(len(ns)) // 長さ 7
fmt.Println(cap(ns)) // 容量 10
スライス演算
code:main.go
ns := []int{10, 20, 30, 40, 50}
n, m := 2, 4
// n番目以降のスライスを取得する
// 先頭からm-1番目までのスライスを取得する
fmt.Println(cap(ns:m)) // 5 // capを指定する
fmt.Println(cap(ms)) // 4
// カット
// 削除
ns = append(ns[:n+copy(nsn:, nsn+1:)]) // このような書き方もできる マップ
code:main.go
// ゼロ値はnil
// makeで初期化
// 容量を指定できる
// リテラルで初期化
m := mapstringint{"x": 10, "y": 20} // 空の場合
fmt.Println(l) // map[]
fmt.Println(n) // map[]
// 存在を確認する
println(i, ok) // 30 true
// キーを指定して削除する
delete(m, "z")
// 削除されていることを確認
j, ok := m"z" // ゼロ値とfalseを返す println(j, ok)
コンポジット型を要素にする
スライスの要素がスライスの場合[][]int
マップの値がスライスの場合map[string][]int
構造体のフィールドの方が構造体
code:main.go
struct {
A struct {
N int
}
}
ユーザ定義型
typeで名前をつけて新しい型を定義する type 型名 基底型
type MyInt intやtype Person struct { Name string }など
型エイリアス
完全に同じ型でキャスト不要
エイリアスの方ではメソッド定義はできない
type Applicant = http.Client