...
Run Format

Source file test/nil.go

Documentation: test

  // 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
  	})
  }
  

View as plain text