– 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を使いこなすには 少し時間がかかりそうだ