| // run | |
| // Copyright 2016 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. | |
| // Ensure that range loops over a string have the requisite side-effects. | |
| package main | |
| import ( | |
| "fmt" | |
| "os" | |
| ) | |
| func check(n int) { | |
| var i int | |
| var r rune | |
| b := make([]byte, n) | |
| for i = range b { | |
| b[i] = byte(i + 1) | |
| } | |
| s := string(b) | |
| // When n == 0, i is untouched by the range loop. | |
| // Picking an initial value of -1 for i makes the | |
| // "want" calculation below correct in all cases. | |
| i = -1 | |
| for i = range s { | |
| b[i] = s[i] | |
| } | |
| if want := n - 1; i != want { | |
| fmt.Printf("index after range with side-effect = %d want %d\n", i, want) | |
| os.Exit(1) | |
| } | |
| i = -1 | |
| r = '\x00' | |
| for i, r = range s { | |
| b[i] = byte(r) | |
| } | |
| if want := n - 1; i != want { | |
| fmt.Printf("index after range with side-effect = %d want %d\n", i, want) | |
| os.Exit(1) | |
| } | |
| if want := rune(n); r != want { | |
| fmt.Printf("rune after range with side-effect = %q want %q\n", r, want) | |
| os.Exit(1) | |
| } | |
| i = -1 | |
| // i is shadowed here, so its value should be unchanged. | |
| for i := range s { | |
| b[i] = s[i] | |
| } | |
| if want := -1; i != want { | |
| fmt.Printf("index after range without side-effect = %d want %d\n", i, want) | |
| os.Exit(1) | |
| } | |
| i = -1 | |
| r = -1 | |
| // i and r are shadowed here, so their values should be unchanged. | |
| for i, r := range s { | |
| b[i] = byte(r) | |
| } | |
| if want := -1; i != want { | |
| fmt.Printf("index after range without side-effect = %d want %d\n", i, want) | |
| os.Exit(1) | |
| } | |
| if want := rune(-1); r != want { | |
| fmt.Printf("rune after range without side-effect = %q want %q\n", r, want) | |
| os.Exit(1) | |
| } | |
| } | |
| func main() { | |
| check(0) | |
| check(1) | |
| check(15) | |
| } |