diff --git a/empty-interface.go b/empty-interface.go new file mode 100644 index 0000000..1c86a2d --- /dev/null +++ b/empty-interface.go @@ -0,0 +1,18 @@ +package main + +import "fmt" + +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) +} diff --git a/errors.go b/errors.go new file mode 100644 index 0000000..95c54d3 --- /dev/null +++ b/errors.go @@ -0,0 +1,29 @@ +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) +} + +func run() error { + return &MyError{ + time.Now(), + "it didn't work", + } +} + +func main() { + if err := run(); err != nil { + fmt.Println(err) + } +} diff --git a/exercise-stringer.go b/exercise-stringer.go new file mode 100644 index 0000000..58a86e6 --- /dev/null +++ b/exercise-stringer.go @@ -0,0 +1,21 @@ +package main + +import "fmt" + +type IPAddr [4]byte + +func (ip IPAddr) String() string { + return fmt.Sprintf("%d.%d.%d.%d", ip[0], ip[1], ip[2], ip[3]) +} + +// TODO: Add a "String() string" method to IPaddr + +func main() { + hosts := map[string]IPAddr{ + "loopback": {127, 0, 0, 1}, + "googleDNS": {8, 8, 8, 8}, + } + for name, ip := range hosts { + fmt.Printf("%v: %v\n", name, ip) + } +} diff --git a/interface-values-with-nil.go b/interface-values-with-nil.go new file mode 100644 index 0000000..a994a9c --- /dev/null +++ b/interface-values-with-nil.go @@ -0,0 +1,36 @@ +package main + +import "fmt" + +type I interface { + M() +} + +type T struct { + S string +} + +func (t *T) M() { + if t == nil { + fmt.Println("") + 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) +} diff --git a/interface-values.go b/interface-values.go new file mode 100644 index 0000000..32e9cdc --- /dev/null +++ b/interface-values.go @@ -0,0 +1,40 @@ +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) + i.M() + + i = F(math.Pi) + describe(i) + i.M() +} + +func describe(i I) { + fmt.Printf("(%v, %T)\n", i, i) +} diff --git a/interfaces-are-satisfied-implicitly.go b/interfaces-are-satisfied-implicitly.go new file mode 100644 index 0000000..a72fc97 --- /dev/null +++ b/interfaces-are-satisfied-implicitly.go @@ -0,0 +1,22 @@ +package main + +import "fmt" + +type I interface { + M() +} + +type T struct { + S string +} + +// This method means type T implements the interface I, +// but we don't need to explicitly declare that it does so. +func (t T) M() { + fmt.Println(t.S) +} + +func main() { + var i I = T{"hello"} + i.M() +} diff --git a/nil-interface-values.go b/nil-interface-values.go new file mode 100644 index 0000000..8253167 --- /dev/null +++ b/nil-interface-values.go @@ -0,0 +1,17 @@ +package main + +import "fmt" + +type I interface { + M() +} + +func main() { + var i I + describe(i) + i.M() +} + +func describe(i I) { + fmt.Printf("(%v, %T)\n", i, i) +} diff --git a/stringer.go b/stringer.go new file mode 100644 index 0000000..6bb7b82 --- /dev/null +++ b/stringer.go @@ -0,0 +1,18 @@ +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} + z := Person{"Zaphod Beeblebrox", 9001} + fmt.Println(a, z) +} diff --git a/type-assertions.go b/type-assertions.go new file mode 100644 index 0000000..0c32ee1 --- /dev/null +++ b/type-assertions.go @@ -0,0 +1,19 @@ +package main + +import "fmt" + +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) // panic + fmt.Println(f) +} diff --git a/type-switches.go b/type-switches.go new file mode 100644 index 0000000..798ad78 --- /dev/null +++ b/type-switches.go @@ -0,0 +1,20 @@ +package main + +import "fmt" + +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) +}