Source file test/nil.go

     1  // run
     2  
     3  // Copyright 2009 The Go Authors. All rights reserved.
     4  // Use of this source code is governed by a BSD-style
     5  // license that can be found in the LICENSE file.
     6  
     7  // Test nil.
     8  
     9  package main
    10  
    11  import (
    12  	"fmt"
    13  	"time"
    14  )
    15  
    16  type T struct {
    17  	i int
    18  }
    19  
    20  type IN interface{}
    21  
    22  func main() {
    23  	var i *int
    24  	var f *float32
    25  	var s *string
    26  	var m map[float32]*int
    27  	var c chan int
    28  	var t *T
    29  	var in IN
    30  	var ta []IN
    31  
    32  	i = nil
    33  	f = nil
    34  	s = nil
    35  	m = nil
    36  	c = nil
    37  	t = nil
    38  	i = nil
    39  	ta = make([]IN, 1)
    40  	ta[0] = nil
    41  
    42  	_, _, _, _, _, _, _, _ = i, f, s, m, c, t, in, ta
    43  
    44  	arraytest()
    45  	chantest()
    46  	maptest()
    47  	slicetest()
    48  }
    49  
    50  func shouldPanic(f func()) {
    51  	defer func() {
    52  		if recover() == nil {
    53  			panic("not panicking")
    54  		}
    55  	}()
    56  	f()
    57  }
    58  
    59  func shouldBlock(f func()) {
    60  	go func() {
    61  		f()
    62  		panic("did not block")
    63  	}()
    64  	time.Sleep(1e7)
    65  }
    66  
    67  // nil array pointer
    68  
    69  func arraytest() {
    70  	var p *[10]int
    71  
    72  	// Looping over indices is fine.
    73  	s := 0
    74  	for i := range p {
    75  		s += i
    76  	}
    77  	if s != 45 {
    78  		panic(s)
    79  	}
    80  
    81  	s = 0
    82  	for i := 0; i < len(p); i++ {
    83  		s += i
    84  	}
    85  	if s != 45 {
    86  		panic(s)
    87  	}
    88  
    89  	// Looping over values is not.
    90  	shouldPanic(func() {
    91  		for i, v := range p {
    92  			s += i + v
    93  		}
    94  	})
    95  
    96  	shouldPanic(func() {
    97  		for i := 0; i < len(p); i++ {
    98  			s += p[i]
    99  		}
   100  	})
   101  }
   102  
   103  // nil channel
   104  // select tests already handle select on nil channel
   105  
   106  func chantest() {
   107  	var ch chan int
   108  
   109  	// nil channel is never ready
   110  	shouldBlock(func() {
   111  		ch <- 1
   112  	})
   113  	shouldBlock(func() {
   114  		<-ch
   115  	})
   116  	shouldBlock(func() {
   117  		x, ok := <-ch
   118  		println(x, ok) // unreachable
   119  	})
   120  
   121  	if len(ch) != 0 {
   122  		panic(len(ch))
   123  	}
   124  	if cap(ch) != 0 {
   125  		panic(cap(ch))
   126  	}
   127  }
   128  
   129  // nil map
   130  
   131  func maptest() {
   132  	var m map[int]int
   133  
   134  	// nil map appears empty
   135  	if len(m) != 0 {
   136  		panic(len(m))
   137  	}
   138  	if m[1] != 0 {
   139  		panic(m[1])
   140  	}
   141  	if x, ok := m[1]; x != 0 || ok {
   142  		panic(fmt.Sprint(x, ok))
   143  	}
   144  
   145  	for k, v := range m {
   146  		panic(k)
   147  		panic(v)
   148  	}
   149  
   150  	// can delete (non-existent) entries
   151  	delete(m, 2)
   152  
   153  	// but cannot be written to
   154  	shouldPanic(func() {
   155  		m[2] = 3
   156  	})
   157  }
   158  
   159  // nil slice
   160  
   161  func slicetest() {
   162  	var x []int
   163  
   164  	// nil slice is just a 0-element slice.
   165  	if len(x) != 0 {
   166  		panic(len(x))
   167  	}
   168  	if cap(x) != 0 {
   169  		panic(cap(x))
   170  	}
   171  
   172  	// no 0-element slices can be read from or written to
   173  	var s int
   174  	shouldPanic(func() {
   175  		s += x[1]
   176  	})
   177  	shouldPanic(func() {
   178  		x[2] = s
   179  	})
   180  }
   181  

View as plain text