github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/test/range.go (about)

     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 the 'for range' construct.
     8  
     9  package main
    10  
    11  // test range over channels
    12  
    13  func gen(c chan int, lo, hi int) {
    14  	for i := lo; i <= hi; i++ {
    15  		c <- i
    16  	}
    17  	close(c)
    18  }
    19  
    20  func seq(lo, hi int) chan int {
    21  	c := make(chan int)
    22  	go gen(c, lo, hi)
    23  	return c
    24  }
    25  
    26  func testchan() {
    27  	s := ""
    28  	for i := range seq('a', 'z') {
    29  		s += string(i)
    30  	}
    31  	if s != "abcdefghijklmnopqrstuvwxyz" {
    32  		println("Wanted lowercase alphabet; got", s)
    33  		panic("fail")
    34  	}
    35  }
    36  
    37  // test that range over slice only evaluates
    38  // the expression after "range" once.
    39  
    40  var nmake = 0
    41  
    42  func makeslice() []int {
    43  	nmake++
    44  	return []int{1, 2, 3, 4, 5}
    45  }
    46  
    47  func testslice() {
    48  	s := 0
    49  	nmake = 0
    50  	for _, v := range makeslice() {
    51  		s += v
    52  	}
    53  	if nmake != 1 {
    54  		println("range called makeslice", nmake, "times")
    55  		panic("fail")
    56  	}
    57  	if s != 15 {
    58  		println("wrong sum ranging over makeslice", s)
    59  		panic("fail")
    60  	}
    61  
    62  	x := []int{10, 20}
    63  	y := []int{99}
    64  	i := 1
    65  	for i, x[i] = range y {
    66  		break
    67  	}
    68  	if i != 0 || x[0] != 10 || x[1] != 99 {
    69  		println("wrong parallel assignment", i, x[0], x[1])
    70  		panic("fail")
    71  	}
    72  }
    73  
    74  func testslice1() {
    75  	s := 0
    76  	nmake = 0
    77  	for i := range makeslice() {
    78  		s += i
    79  	}
    80  	if nmake != 1 {
    81  		println("range called makeslice", nmake, "times")
    82  		panic("fail")
    83  	}
    84  	if s != 10 {
    85  		println("wrong sum ranging over makeslice", s)
    86  		panic("fail")
    87  	}
    88  }
    89  
    90  // test that range over array only evaluates
    91  // the expression after "range" once.
    92  
    93  func makearray() [5]int {
    94  	nmake++
    95  	return [5]int{1, 2, 3, 4, 5}
    96  }
    97  
    98  func testarray() {
    99  	s := 0
   100  	nmake = 0
   101  	for _, v := range makearray() {
   102  		s += v
   103  	}
   104  	if nmake != 1 {
   105  		println("range called makearray", nmake, "times")
   106  		panic("fail")
   107  	}
   108  	if s != 15 {
   109  		println("wrong sum ranging over makearray", s)
   110  		panic("fail")
   111  	}
   112  }
   113  
   114  func testarray1() {
   115  	s := 0
   116  	nmake = 0
   117  	for i := range makearray() {
   118  		s += i
   119  	}
   120  	if nmake != 1 {
   121  		println("range called makearray", nmake, "times")
   122  		panic("fail")
   123  	}
   124  	if s != 10 {
   125  		println("wrong sum ranging over makearray", s)
   126  		panic("fail")
   127  	}
   128  }
   129  
   130  func makearrayptr() *[5]int {
   131  	nmake++
   132  	return &[5]int{1, 2, 3, 4, 5}
   133  }
   134  
   135  func testarrayptr() {
   136  	nmake = 0
   137  	x := len(makearrayptr())
   138  	if x != 5 || nmake != 1 {
   139  		println("len called makearrayptr", nmake, "times and got len", x)
   140  		panic("fail")
   141  	}
   142  	nmake = 0
   143  	x = cap(makearrayptr())
   144  	if x != 5 || nmake != 1 {
   145  		println("cap called makearrayptr", nmake, "times and got len", x)
   146  		panic("fail")
   147  	}
   148  	s := 0
   149  	nmake = 0
   150  	for _, v := range makearrayptr() {
   151  		s += v
   152  	}
   153  	if nmake != 1 {
   154  		println("range called makearrayptr", nmake, "times")
   155  		panic("fail")
   156  	}
   157  	if s != 15 {
   158  		println("wrong sum ranging over makearrayptr", s)
   159  		panic("fail")
   160  	}
   161  }
   162  
   163  func testarrayptr1() {
   164  	s := 0
   165  	nmake = 0
   166  	for i := range makearrayptr() {
   167  		s += i
   168  	}
   169  	if nmake != 1 {
   170  		println("range called makearrayptr", nmake, "times")
   171  		panic("fail")
   172  	}
   173  	if s != 10 {
   174  		println("wrong sum ranging over makearrayptr", s)
   175  		panic("fail")
   176  	}
   177  }
   178  
   179  // test that range over string only evaluates
   180  // the expression after "range" once.
   181  
   182  func makestring() string {
   183  	nmake++
   184  	return "abcd☺"
   185  }
   186  
   187  func teststring() {
   188  	var s rune
   189  	nmake = 0
   190  	for _, v := range makestring() {
   191  		s += v
   192  	}
   193  	if nmake != 1 {
   194  		println("range called makestring", nmake, "times")
   195  		panic("fail")
   196  	}
   197  	if s != 'a'+'b'+'c'+'d'+'☺' {
   198  		println("wrong sum ranging over makestring", s)
   199  		panic("fail")
   200  	}
   201  }
   202  
   203  func teststring1() {
   204  	s := 0
   205  	nmake = 0
   206  	for i := range makestring() {
   207  		s += i
   208  	}
   209  	if nmake != 1 {
   210  		println("range called makestring", nmake, "times")
   211  		panic("fail")
   212  	}
   213  	if s != 10 {
   214  		println("wrong sum ranging over makestring", s)
   215  		panic("fail")
   216  	}
   217  }
   218  
   219  // test that range over map only evaluates
   220  // the expression after "range" once.
   221  
   222  func makemap() map[int]int {
   223  	nmake++
   224  	return map[int]int{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: '☺'}
   225  }
   226  
   227  func testmap() {
   228  	s := 0
   229  	nmake = 0
   230  	for _, v := range makemap() {
   231  		s += v
   232  	}
   233  	if nmake != 1 {
   234  		println("range called makemap", nmake, "times")
   235  		panic("fail")
   236  	}
   237  	if s != 'a'+'b'+'c'+'d'+'☺' {
   238  		println("wrong sum ranging over makemap", s)
   239  		panic("fail")
   240  	}
   241  }
   242  
   243  func testmap1() {
   244  	s := 0
   245  	nmake = 0
   246  	for i := range makemap() {
   247  		s += i
   248  	}
   249  	if nmake != 1 {
   250  		println("range called makemap", nmake, "times")
   251  		panic("fail")
   252  	}
   253  	if s != 10 {
   254  		println("wrong sum ranging over makemap", s)
   255  		panic("fail")
   256  	}
   257  }
   258  
   259  // test that range evaluates the index and value expressions
   260  // exactly once per iteration.
   261  
   262  var ncalls = 0
   263  
   264  func getvar(p *int) *int {
   265  	ncalls++
   266  	return p
   267  }
   268  
   269  func testcalls() {
   270  	var i, v int
   271  	si := 0
   272  	sv := 0
   273  	for *getvar(&i), *getvar(&v) = range [2]int{1, 2} {
   274  		si += i
   275  		sv += v
   276  	}
   277  	if ncalls != 4 {
   278  		println("wrong number of calls:", ncalls, "!= 4")
   279  		panic("fail")
   280  	}
   281  	if si != 1 || sv != 3 {
   282  		println("wrong sum in testcalls", si, sv)
   283  		panic("fail")
   284  	}
   285  
   286  	ncalls = 0
   287  	for *getvar(&i), *getvar(&v) = range [0]int{} {
   288  		println("loop ran on empty array")
   289  		panic("fail")
   290  	}
   291  	if ncalls != 0 {
   292  		println("wrong number of calls:", ncalls, "!= 0")
   293  		panic("fail")
   294  	}
   295  }
   296  
   297  func main() {
   298  	testchan()
   299  	testarray()
   300  	testarray1()
   301  	testarrayptr()
   302  	testarrayptr1()
   303  	testslice()
   304  	testslice1()
   305  	teststring()
   306  	teststring1()
   307  	testmap()
   308  	testmap1()
   309  	testcalls()
   310  }