メソッド
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := Vertex{3, 4} fmt.Println(v.Abs()) // 5 x := Vertex{5, 12} fmt.Println(x.Abs()) // 13 }
package main import ( "fmt" "math" ) type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } func main() { f := MyFloat(-math.Sqrt2) fmt.Println(f.Abs()) // 1.4142135623730951 }
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func (v *Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} fmt.Println(v.Abs()) // 5 v.Scale(10) fmt.Println(v.Abs()) // 50 }
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func Abs(v Vertex) float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func Scale(v *Vertex, f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} fmt.Println(Abs(v)) // 5 Scale(&v, 10) fmt.Println(Abs(v)) // 50 }
package main import "fmt" type Vertex struct { X, Y float64 } func (v *Vertex) Scale(f float64) { v.X = v.X * f v.Y = v.Y * f } func ScaleFunc(v *Vertex, f float64) { v.X = v.X * f v.Y = v.Y * f } func main() { v := Vertex{3, 4} fmt.Println(v) // {3 4} v.Scale(2) fmt.Println(v) // {6 8} ScaleFunc(&v, 10) fmt.Println(v) // {60 80} }
package main import ( "fmt" "math" ) type Vertex struct { X, Y float64 } func (v Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func AbsFunc(v Vertex) float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) } func main() { v := Vertex{3, 4} fmt.Println(v.Abs()) // 5 fmt.Println(AbsFunc(v)) // 5 p := &Vertex{4, 3} fmt.Println(p.Abs()) // (*p).Abs()と解釈される // 5 fmt.Println(AbsFunc(*p)) // AbsFunc(p)とするとエラー // 5 }
interface
package main import ( "fmt" "math" ) type Abser interface { Abs() float64 } func main() { var a Abser f := MyFloat(-math.Sqrt2) v := Vertex{3, 4} a = f fmt.Println(a.Abs()) // 1.4142135623730951 a = &v fmt.Println(a.Abs()) // 5 // エラー // a = v // VertexはAbs()を持っていない // Abs()を持っているのは*Vertex } type MyFloat float64 func (f MyFloat) Abs() float64 { if f < 0 { return float64(-f) } return float64(f) } type Vertex struct { X, Y float64 } func (v *Vertex) Abs() float64 { return math.Sqrt(v.X*v.X + v.Y*v.Y) }
package main import "fmt" type I interface { M() } type T struct { S string } // ここで、T はinterface I を実装することを意味しています // しかしそのことを明示的に宣言する必要はありません func (t T) M() { fmt.Println(t.S) } func main() { var i I = T{"hello"} i.M() // hello }
package main import ( "fmt" "math" ) type I interface { M() } type T struct { S string } func (t *T) M() { fmt.Println(t.S) } type F float64 func (f F) M() { fmt.Println(f) } func main() { var i I i = &T{"Hello"} describe(i) // (&{Hello}, *main.T) i.M() // Hello i = F(math.Pi) describe(i) // (3.141592653589793, main.F) i.M() // 3.141592653589793 } func describe(i I) { fmt.Printf("(%v, %T)\n", i, i) }
package main import "fmt" type I interface { M() } type T struct { S string } func (t *T) M() { if t == nil { fmt.Println("<nil>") return } fmt.Println(t.S) } func main() { var i I var t *T i = t describe(i) // (<nil>, *main.T) i.M() // <nil> i = &T{"hello"} describe(i) // (&{hello}, *main.T) i.M() // hello } func describe(i I) { fmt.Printf("(%v, %T)\n", i, i) }
package main import "fmt" func main() { // 空のインターフェース var i interface{} describe(i) // (<nil>, <nil>) // どの型でも受け入れられる i = 42 describe(i) // (42, int) i = "hello" describe(i) // (hello, string) } func describe(i interface{}) { fmt.Printf("(%v, %T)\n", i, i) }
Type assertions
package main import "fmt" func main() { var i interface{} = "hello" s := i.(string) fmt.Println(s) // hello s, ok := i.(string) fmt.Println(s, ok) // hello true f, ok := i.(float64) fmt.Println(f, ok) // 0 false // panic // f = i.(float64) // fmt.Println(f) }
package main import "fmt" func do(i interface{}) { switch v := i.(type) { case int: fmt.Println(v) case string: fmt.Println(v) default: fmt.Printf("I don't know about type %T!\n", v) } } func main() { do(21) // 21 do("hello") // hello do(true) // I don't know about type bool! }
Stringers
package main import "fmt" type Person struct { Name string Age int } func (p Person) String() string { return fmt.Sprintf("%v (%v years)", p.Name, p.Age) } func main() { a := Person{"Arthur Dent", 42} fmt.Println(a) // Arthur Dent (42 years) }
error
package main import ( "fmt" "time" ) type MyError struct { When time.Time What string } func (e *MyError) Error() string { return fmt.Sprintf("at %v, %s", e.When, e.What) } // errorは組み込みのinterface // type error interface { // Error() string // } func run() error { return &MyError{time.Now(), "it didn't work",} } func main() { if err := run(); err != nil {fmt.Println(err)} // at 2009-11-10 23:00:00 +0000 UTC m=+0.000000001, it didn't work }
panic
エラーを故意に起こすやつ
a := []int{1, 2, 3} for i := 0; i < 10; i++ { if i >= len(a) { panic(errors.New("index out of range")) } fmt.Println(a[i]) }
Reader
package main import ( "fmt" "io" "strings" ) func main() { r := strings.NewReader("Hello, Reader!") b := make([]byte, 8) for { n, err := r.Read(b) fmt.Printf("n = %v err = %v b = %v\n", n, err, b) fmt.Printf("b[:n] = %q\n", b[:n]) if err == io.EOF { break } } // n = 8 err = <nil> b = [72 101 108 108 111 44 32 82] // b[:n] = "Hello, R" // n = 6 err = <nil> b = [101 97 100 101 114 33 32 82] // b[:n] = "eader!" // n = 0 err = EOF b = [101 97 100 101 114 33 32 82] // b[:n] = "" }