| // run | |
| // Copyright 2009 The Go Authors. All rights reserved. | |
| // Use of this source code is governed by a BSD-style | |
| // license that can be found in the LICENSE file. | |
| // Test nil. | |
| package main | |
| import ( | |
| "fmt" | |
| "time" | |
| ) | |
| type T struct { | |
| i int | |
| } | |
| type IN interface{} | |
| func main() { | |
| var i *int | |
| var f *float32 | |
| var s *string | |
| var m map[float32]*int | |
| var c chan int | |
| var t *T | |
| var in IN | |
| var ta []IN | |
| i = nil | |
| f = nil | |
| s = nil | |
| m = nil | |
| c = nil | |
| t = nil | |
| i = nil | |
| ta = make([]IN, 1) | |
| ta[0] = nil | |
| _, _, _, _, _, _, _, _ = i, f, s, m, c, t, in, ta | |
| arraytest() | |
| chantest() | |
| maptest() | |
| slicetest() | |
| } | |
| func shouldPanic(f func()) { | |
| defer func() { | |
| if recover() == nil { | |
| panic("not panicking") | |
| } | |
| }() | |
| f() | |
| } | |
| func shouldBlock(f func()) { | |
| go func() { | |
| f() | |
| panic("did not block") | |
| }() | |
| time.Sleep(1e7) | |
| } | |
| // nil array pointer | |
| func arraytest() { | |
| var p *[10]int | |
| // Looping over indices is fine. | |
| s := 0 | |
| for i := range p { | |
| s += i | |
| } | |
| if s != 45 { | |
| panic(s) | |
| } | |
| s = 0 | |
| for i := 0; i < len(p); i++ { | |
| s += i | |
| } | |
| if s != 45 { | |
| panic(s) | |
| } | |
| // Looping over values is not. | |
| shouldPanic(func() { | |
| for i, v := range p { | |
| s += i + v | |
| } | |
| }) | |
| shouldPanic(func() { | |
| for i := 0; i < len(p); i++ { | |
| s += p[i] | |
| } | |
| }) | |
| } | |
| // nil channel | |
| // select tests already handle select on nil channel | |
| func chantest() { | |
| var ch chan int | |
| // nil channel is never ready | |
| shouldBlock(func() { | |
| ch <- 1 | |
| }) | |
| shouldBlock(func() { | |
| <-ch | |
| }) | |
| shouldBlock(func() { | |
| x, ok := <-ch | |
| println(x, ok) // unreachable | |
| }) | |
| if len(ch) != 0 { | |
| panic(len(ch)) | |
| } | |
| if cap(ch) != 0 { | |
| panic(cap(ch)) | |
| } | |
| } | |
| // nil map | |
| func maptest() { | |
| var m map[int]int | |
| // nil map appears empty | |
| if len(m) != 0 { | |
| panic(len(m)) | |
| } | |
| if m[1] != 0 { | |
| panic(m[1]) | |
| } | |
| if x, ok := m[1]; x != 0 || ok { | |
| panic(fmt.Sprint(x, ok)) | |
| } | |
| for k, v := range m { | |
| panic(k) | |
| panic(v) | |
| } | |
| // can delete (non-existent) entries | |
| delete(m, 2) | |
| // but cannot be written to | |
| shouldPanic(func() { | |
| m[2] = 3 | |
| }) | |
| } | |
| // nil slice | |
| func slicetest() { | |
| var x []int | |
| // nil slice is just a 0-element slice. | |
| if len(x) != 0 { | |
| panic(len(x)) | |
| } | |
| if cap(x) != 0 { | |
| panic(cap(x)) | |
| } | |
| // no 0-element slices can be read from or written to | |
| var s int | |
| shouldPanic(func() { | |
| s += x[1] | |
| }) | |
| shouldPanic(func() { | |
| x[2] = s | |
| }) | |
| } |