98 lines
1.7 KiB
Go
98 lines
1.7 KiB
Go
package main
|
|
|
|
import "fmt"
|
|
|
|
var (
|
|
s []int
|
|
p *int
|
|
f func()
|
|
i interface{}
|
|
m map[int]int
|
|
c chan int
|
|
)
|
|
|
|
func main() {
|
|
fmt.Println("Exercise nil objects:")
|
|
status()
|
|
|
|
// initialize objects
|
|
s = make([]int, 1)
|
|
p = &s[0] // yes, reference element of slice just created
|
|
f = func() { fmt.Println("function call") }
|
|
i = user(0) // see user defined type just below
|
|
m = make(map[int]int)
|
|
c = make(chan int, 1)
|
|
|
|
fmt.Println("\nExercise objects after initialization:")
|
|
status()
|
|
}
|
|
|
|
type user int
|
|
|
|
func (user) m() {
|
|
fmt.Println("method call")
|
|
}
|
|
|
|
func status() {
|
|
trySlice()
|
|
tryPointer()
|
|
tryFunction()
|
|
tryInterface()
|
|
tryMap()
|
|
tryChannel()
|
|
}
|
|
|
|
func reportPanic() {
|
|
if x := recover(); x != nil {
|
|
fmt.Println("panic:", x)
|
|
}
|
|
}
|
|
|
|
func trySlice() {
|
|
defer reportPanic()
|
|
fmt.Println("s[0] =", s[0])
|
|
}
|
|
|
|
func tryPointer() {
|
|
defer reportPanic()
|
|
fmt.Println("*p =", *p)
|
|
}
|
|
|
|
func tryFunction() {
|
|
defer reportPanic()
|
|
f()
|
|
}
|
|
|
|
func tryInterface() {
|
|
defer reportPanic()
|
|
|
|
// normally the nil identifier accesses a nil value for one of
|
|
// six predefined types. In a type switch however, nil can be used
|
|
// as a type. In this case, it matches the nil interface.
|
|
switch i.(type) {
|
|
case nil:
|
|
fmt.Println("i is nil interface")
|
|
case interface {
|
|
m()
|
|
}:
|
|
fmt.Println("i has method m")
|
|
}
|
|
|
|
// assert type with method and then call method
|
|
i.(interface {
|
|
m()
|
|
}).m()
|
|
}
|
|
|
|
func tryMap() {
|
|
defer reportPanic()
|
|
m[0] = 0
|
|
fmt.Println("m[0] =", m[0])
|
|
}
|
|
|
|
func tryChannel() {
|
|
defer reportPanic()
|
|
close(c)
|
|
fmt.Println("channel closed")
|
|
}
|