github.com/mh-cbon/go@v0.0.0-20160603070303-9e112a3fe4c0/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 n := 0 36 for range seq('a', 'z') { 37 n++ 38 } 39 if n != 26 { 40 println("testchan wrong count", n, "want 26") 41 } 42 } 43 44 // test that range over slice only evaluates 45 // the expression after "range" once. 46 47 var nmake = 0 48 49 func makeslice() []int { 50 nmake++ 51 return []int{1, 2, 3, 4, 5} 52 } 53 54 func testslice() { 55 s := 0 56 nmake = 0 57 for _, v := range makeslice() { 58 s += v 59 } 60 if nmake != 1 { 61 println("range called makeslice", nmake, "times") 62 panic("fail") 63 } 64 if s != 15 { 65 println("wrong sum ranging over makeslice", s) 66 panic("fail") 67 } 68 69 x := []int{10, 20} 70 y := []int{99} 71 i := 1 72 for i, x[i] = range y { 73 break 74 } 75 if i != 0 || x[0] != 10 || x[1] != 99 { 76 println("wrong parallel assignment", i, x[0], x[1]) 77 panic("fail") 78 } 79 } 80 81 func testslice1() { 82 s := 0 83 nmake = 0 84 for i := range makeslice() { 85 s += i 86 } 87 if nmake != 1 { 88 println("range called makeslice", nmake, "times") 89 panic("fail") 90 } 91 if s != 10 { 92 println("wrong sum ranging over makeslice", s) 93 panic("fail") 94 } 95 } 96 97 func testslice2() { 98 n := 0 99 nmake = 0 100 for range makeslice() { 101 n++ 102 } 103 if nmake != 1 { 104 println("range called makeslice", nmake, "times") 105 panic("fail") 106 } 107 if n != 5 { 108 println("wrong count ranging over makeslice", n) 109 panic("fail") 110 } 111 } 112 113 // test that range over array only evaluates 114 // the expression after "range" once. 115 116 func makearray() [5]int { 117 nmake++ 118 return [5]int{1, 2, 3, 4, 5} 119 } 120 121 func testarray() { 122 s := 0 123 nmake = 0 124 for _, v := range makearray() { 125 s += v 126 } 127 if nmake != 1 { 128 println("range called makearray", nmake, "times") 129 panic("fail") 130 } 131 if s != 15 { 132 println("wrong sum ranging over makearray", s) 133 panic("fail") 134 } 135 } 136 137 func testarray1() { 138 s := 0 139 nmake = 0 140 for i := range makearray() { 141 s += i 142 } 143 if nmake != 1 { 144 println("range called makearray", nmake, "times") 145 panic("fail") 146 } 147 if s != 10 { 148 println("wrong sum ranging over makearray", s) 149 panic("fail") 150 } 151 } 152 153 func testarray2() { 154 n := 0 155 nmake = 0 156 for range makearray() { 157 n++ 158 } 159 if nmake != 1 { 160 println("range called makearray", nmake, "times") 161 panic("fail") 162 } 163 if n != 5 { 164 println("wrong count ranging over makearray", n) 165 panic("fail") 166 } 167 } 168 169 func makearrayptr() *[5]int { 170 nmake++ 171 return &[5]int{1, 2, 3, 4, 5} 172 } 173 174 func testarrayptr() { 175 nmake = 0 176 x := len(makearrayptr()) 177 if x != 5 || nmake != 1 { 178 println("len called makearrayptr", nmake, "times and got len", x) 179 panic("fail") 180 } 181 nmake = 0 182 x = cap(makearrayptr()) 183 if x != 5 || nmake != 1 { 184 println("cap called makearrayptr", nmake, "times and got len", x) 185 panic("fail") 186 } 187 s := 0 188 nmake = 0 189 for _, v := range makearrayptr() { 190 s += v 191 } 192 if nmake != 1 { 193 println("range called makearrayptr", nmake, "times") 194 panic("fail") 195 } 196 if s != 15 { 197 println("wrong sum ranging over makearrayptr", s) 198 panic("fail") 199 } 200 } 201 202 func testarrayptr1() { 203 s := 0 204 nmake = 0 205 for i := range makearrayptr() { 206 s += i 207 } 208 if nmake != 1 { 209 println("range called makearrayptr", nmake, "times") 210 panic("fail") 211 } 212 if s != 10 { 213 println("wrong sum ranging over makearrayptr", s) 214 panic("fail") 215 } 216 } 217 218 func testarrayptr2() { 219 n := 0 220 nmake = 0 221 for range makearrayptr() { 222 n++ 223 } 224 if nmake != 1 { 225 println("range called makearrayptr", nmake, "times") 226 panic("fail") 227 } 228 if n != 5 { 229 println("wrong count ranging over makearrayptr", n) 230 panic("fail") 231 } 232 } 233 234 // test that range over string only evaluates 235 // the expression after "range" once. 236 237 func makestring() string { 238 nmake++ 239 return "abcd☺" 240 } 241 242 func teststring() { 243 var s rune 244 nmake = 0 245 for _, v := range makestring() { 246 s += v 247 } 248 if nmake != 1 { 249 println("range called makestring", nmake, "times") 250 panic("fail") 251 } 252 if s != 'a'+'b'+'c'+'d'+'☺' { 253 println("wrong sum ranging over makestring", s) 254 panic("fail") 255 } 256 } 257 258 func teststring1() { 259 s := 0 260 nmake = 0 261 for i := range makestring() { 262 s += i 263 } 264 if nmake != 1 { 265 println("range called makestring", nmake, "times") 266 panic("fail") 267 } 268 if s != 10 { 269 println("wrong sum ranging over makestring", s) 270 panic("fail") 271 } 272 } 273 274 func teststring2() { 275 n := 0 276 nmake = 0 277 for range makestring() { 278 n++ 279 } 280 if nmake != 1 { 281 println("range called makestring", nmake, "times") 282 panic("fail") 283 } 284 if n != 5 { 285 println("wrong count ranging over makestring", n) 286 panic("fail") 287 } 288 } 289 290 // test that range over map only evaluates 291 // the expression after "range" once. 292 293 func makemap() map[int]int { 294 nmake++ 295 return map[int]int{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: '☺'} 296 } 297 298 func testmap() { 299 s := 0 300 nmake = 0 301 for _, v := range makemap() { 302 s += v 303 } 304 if nmake != 1 { 305 println("range called makemap", nmake, "times") 306 panic("fail") 307 } 308 if s != 'a'+'b'+'c'+'d'+'☺' { 309 println("wrong sum ranging over makemap", s) 310 panic("fail") 311 } 312 } 313 314 func testmap1() { 315 s := 0 316 nmake = 0 317 for i := range makemap() { 318 s += i 319 } 320 if nmake != 1 { 321 println("range called makemap", nmake, "times") 322 panic("fail") 323 } 324 if s != 10 { 325 println("wrong sum ranging over makemap", s) 326 panic("fail") 327 } 328 } 329 330 func testmap2() { 331 n := 0 332 nmake = 0 333 for range makemap() { 334 n++ 335 } 336 if nmake != 1 { 337 println("range called makemap", nmake, "times") 338 panic("fail") 339 } 340 if n != 5 { 341 println("wrong count ranging over makemap", n) 342 panic("fail") 343 } 344 } 345 346 // test that range evaluates the index and value expressions 347 // exactly once per iteration. 348 349 var ncalls = 0 350 351 func getvar(p *int) *int { 352 ncalls++ 353 return p 354 } 355 356 func testcalls() { 357 var i, v int 358 si := 0 359 sv := 0 360 for *getvar(&i), *getvar(&v) = range [2]int{1, 2} { 361 si += i 362 sv += v 363 } 364 if ncalls != 4 { 365 println("wrong number of calls:", ncalls, "!= 4") 366 panic("fail") 367 } 368 if si != 1 || sv != 3 { 369 println("wrong sum in testcalls", si, sv) 370 panic("fail") 371 } 372 373 ncalls = 0 374 for *getvar(&i), *getvar(&v) = range [0]int{} { 375 println("loop ran on empty array") 376 panic("fail") 377 } 378 if ncalls != 0 { 379 println("wrong number of calls:", ncalls, "!= 0") 380 panic("fail") 381 } 382 } 383 384 func main() { 385 testchan() 386 testarray() 387 testarray1() 388 testarray2() 389 testarrayptr() 390 testarrayptr1() 391 testarrayptr2() 392 testslice() 393 testslice1() 394 testslice2() 395 teststring() 396 teststring1() 397 teststring2() 398 testmap() 399 testmap1() 400 testmap2() 401 testcalls() 402 }