pointer
package main import "fmt" func main() { i, j := 42, 930 p := &i // iを指すポインタpを宣言 fmt.Println(*p) // 42 *p = 21 // iの値を書き換える fmt.Println(i) // 21 p = &j // pの指す変数をjに変更 *p = *p / 30 // pを通してjの値を書き換える fmt.Println(j) // 31 }
struct
ここでTask
という構造体を作ることを考える。
構造体型もtypeを用いて宣言し,構造体名のあとにそのフィールドを記述する。 各フィールドは、大文字で始まる場合はpublic,小文字の場合はパッケージ内に閉じたprivate変数となる。
type Task struct { ID int // public Detail string // public done bool // private }
この構造体の使い方は次のようになる。
func main() { var task Task = Task{ ID: 1, Detail: "buy the milk", done: true, } fmt.Println(task.ID) // 1 fmt.Println(task.Detail) // "buy the milk" fmt.Println(task.done) // true }
package main import "fmt" type Vertex struct { X int Y int } func main() { v := Vertex{1, 2} // メンバ変数は順番通りに宣言すれば変数名を明示しなくてもよい fmt.Println(v) // {1, 2} v.X = 4 fmt.Println(v.X) // 4 p := &v p.X = 10 // (*p).X とも書ける fmt.Println(v) // {10, 2} }
package main import "fmt" type Vertex struct { X, Y int } var ( v1 = Vertex{1, 2} // has type Vertex v2 = Vertex{X: 1} // Y:0 is implicit v3 = Vertex{} // X:0 and Y:0 p = &Vertex{1, 2} // has type *Vertex ) func main() { fmt.Println(v1, v2, v3, p) // {1 2} {1 0} {0 0} &{1 2} }
array
package main import "fmt" func main() { var a [2]string a[0] = "Hello" a[1] = "World" fmt.Println(a[0], a[1]) // Hello World fmt.Println(a) // [Hello World] primes := [6]int{2, 3, 5, 7, 11, 13} fmt.Println(primes) // [2 3 5 7 11 13] }
slice
package main import "fmt" func main() { primes := [6]int{2, 3, 5, 7, 11, 13} var s []int = primes[1:4] fmt.Println(s) // [3 5 7] }
package main import "fmt" func main() { nums := []int{0, 1, 2, 3} // nums := [4]int(0, 1, 2, 3) と同じ fmt.Println(nums) // [0 1 2 3] a := nums[0:2] fmt.Println(a) // [0 1] a[1] = 10 fmt.Println(a) // [0 10] fmt.Println(nums) // [0 10 2 3] }
package main import "fmt" func main() { s := []int{2, 3, 5, 7, 11, 13} s = s[1:4] fmt.Println(s) // [3 5 7] s = s[:2] fmt.Println(s) // [3 5] s = s[1:] fmt.Println(s) // [5] }
length, capacity
package main import "fmt" func main() { s := []int{2, 3, 5, 7, 11, 13} printSlice(s) // len=6 cap=6, [2 3 5 7 11 13] s = s[:0] printSlice(s) // len=0 cap=6, [] // Extend its length. s = s[:4] printSlice(s) // len=4 cap=6, [2 3 5 7] // Drop its first two values. s = s[2:] printSlice(s) // len=2 cap=4, [5 7] s = s[0:4] printSlice(s) // len=4 cap=4, [5 7 11 13] s = s[0:8] printSlice(s) // panic } func printSlice(s []int) { fmt.Printf("len=%d cap=%d, %v\n", len(s), cap(s), s) }
package main import "fmt" func main() { var s []int fmt.Println(s, len(s), cap(s)) // [] 0 0 if s == nil { fmt.Println("nil!") // nil! } }
package main import "fmt" func main() { var s []int printSlice(s) // len=0 cap=0 [] s = append(s, 0) printSlice(s) // len=1 cap=2 [0] s = append(s, 1) printSlice(s) // len=2 cap=2 [0 1] s = append(s, 2, 3, 4) printSlice(s) len=5 cap=8 [0 1 2 3 4] } func printSlice(s []int) { fmt.Printf("len=%d cap=%d %v\n", len(s), cap(s), s) }
make
package main import "fmt" func main() { a := make([]int, 5) printSlice(a) // len=5 cap=5 [0 0 0 0 0] b := make([]int, 0, 5) printSlice(b) // len=0 cap=5 [] c := b[:2] printSlice(c) // len=2 cap=5 [0 0] d := c[2:5] printSlice(d) // len=3 cap=3 [0 0 0] } func printSlice(x []int) { fmt.Printf("len=%d cap=%d %v\n",len(x), cap(x), x) }
二重配列
package main import ( "fmt" "strings" ) func main() { // Create a tic-tac-toe board. board := [][]string{ []string{"_", "_", "_"}, []string{"_", "_", "_"}, } // The players take turns. board[0][0] = "X" board[0][2] = "O" board[1][0] = "O" for i := 0; i < len(board); i++ { fmt.Printf("%s\n", strings.Join(board[i], " ")) } // X _ O // O _ _ }
Range
package main import "fmt" var pow = []int{1, 2, 4, 8, 16, 32, 64, 128} func main() { for i, v := range pow { fmt.Println(i, v) } // 0 1 // 1 2 // 2 4 // 3 8 // 4 16 // 5 32 // 6 64 // 7 128 }
package main import "fmt" func main() { pow := make([]int, 10) for i := range pow { pow[i] = 1 << i // == 2**i } // 使わない変数は _ を使う (未使用の変数があるとエラーが出るため) for _, value := range pow { fmt.Printf("%d\n", value) } }
map
// マップの宣言 var month map[int]string = map[int]string{} // キーを指定して値を保存 month[1] = "January" month[2] = "February" fmt.Println(month) // map[1:January 2:February
package main import "fmt" type Vertex struct { Lat, Long float64 } var m map[string]Vertex func main() { // makeでmapを作成 m = make(map[string]Vertex) m["Bell Labs"] = Vertex{ 40.68433, -74.39967, } m["test"] = Vertex{ 10.0, -5.0, } fmt.Println(m["Bell Labs"]) // {40.68433 -74.39967} fmt.Println(m["test"]) // {10 -5} }
package main import "fmt" type Vertex struct { Lat, Long float64 } var m = map[string]Vertex{ "Bell Labs": Vertex{ 40.68433, -74.39967, }, "Google": Vertex{ 37.42202, -122.08408, }, } func main() { fmt.Println(m) // map[Bell Labs:{40.68433 -74.39967} Google:{37.42202 -122.08408}] }
package main import "fmt" func main() { m := make(map[string]int) m["Answer"] = 42 fmt.Println("The value:", m["Answer"]) // The value: 42 m["Answer"] = 48 fmt.Println("The value:", m["Answer"]) // The value: 48 v1, ok := m["Answer"] fmt.Println("The value:", v1, "Present?", ok) // The value: 48 Present? true delete(m, "Answer") fmt.Println("The value:", m["Answer"]) // The value: 0 v2, ok := m["Answer"] fmt.Println("The value:", v2, "Present?", ok) // The value: 0 Present? false }
function values
package main import ( "fmt" "math" ) func compute(fn func(float64, float64) float64) float64 { return fn(3, 4) } func main() { hypot := func(x, y float64) float64 { return math.Sqrt(x*x + y*y) } fmt.Println(hypot(5, 12)) // 13 fmt.Println(compute(hypot)) // 5 fmt.Println(compute(math.Pow)) // 81 }
クロージャ
package main import "fmt" func adder() func(int) int { sum := 0 return func(x int) int { sum += x return sum } } func main() { pos, neg := adder(), adder() for i := 0; i < 5; i++ { fmt.Println(pos(i), neg(-2*i)) } } // 0 0 // 1 -2 // 3 -6 // 6 -12 // 10 -20
参考
第3章 型システム―型を用いた安全なプログラミング:はじめてのGo―シンプルな言語仕様,型システム,並行処理|gihyo.jp … 技術評論社