– Interface values with nil underlying values
If the concrete value inside the interface itself is nil, the method will be called with a nil receiver.
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) i.M() i = &T{"hello"} describe(i) i.M() } func describe(i I){ fmt.Printf("(%v, %T)\n", i, i) }
– Nil interface values
A nil interface value holds neither value nor concrete type.
type I interface { M() } func main(){ var i I describe(i) i.M() } func describe(i I){ fmt.Printf("(%v, %T)\n", i, i) }
(
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x0 pc=0x49abcf]
goroutine 1 [running]:
main.main()
/home/vagrant/next/go/hello.go:14 +0x8f
– The empty interface
The interface type that specifies zero methods is known as the empty interface: interface{}
func main(){ var i interface{} describe(i) i = 42 describe(i) i = "hello" describe(i) } func describe(i interface{}){ fmt.Printf("(%v, %T)\n", i, i) }
– Type assertions
A type assertion provides access to an interface value’s underlying concrete value.
func main(){ var i interface{} = "hello" s := i.(string) fmt.Println(s) s, ok := i.(string) fmt.Println(s, ok) f, ok := i.(float64) fmt.Println(f, ok) f = i.(float64) fmt.Println(f) }
– Type switches
A type switch is a construct that permits several type assertions in series.
func do(i interface{}){ switch v := i.(type){ case int: fmt.Printf("Twice %v is %v\n", v, v*2) case string: fmt.Printf("%q is %v bytes long\n", v, len(v)) default: fmt.Printf("I don't know about type %T!\n", v) } } func main(){ do(21) do("hello") do(true) }
– Stringers
A stringer is a type that can describe itself as a string. The fmt package look for this interface to print values.
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} z := Person{"Zaphod Beeblebrox", 9001} fmt.Println(a, z) }
### Errors
Go programs express error state with error values.
type MyError struct { When time.Time What string } func (e *MyError) Error() string{ return fmt.Sprintf("at %v, %s", e.When, e.What) } func run() error { return &MyError { time.Now(), "it didn't work", } } func main(){ if err := run(); err != nil { fmt.Println(err) } }
### Readers
The io package specifies the io.Reader interface, which represents the read end of a stream of data.
import ( "fmt" "io" "strings" ) func main(){ r := strings.NewReader("Hello, Reader!") b := make([]byte, 8) for { n, err := r.Raed(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 } } }
### Images
import ( "fmt" "image" ) func main(){ m := image.NewRGBA(image.Rect(0, 0, 100, 100)) fmt.Println(m.Bounds()) fmt.Println(m.At(0, 0).RGBA()) }
Methods と Interfaceを使いこなすには 少し時間がかかりそうだ