-// $G $F.go && $L $F.$A && ./$A.out
+// 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 switch statements.
+
package main
+import "os"
+
func assert(cond bool, msg string) {
if !cond {
- print "assertion fail: ", msg, "\n";
- panic 1;
+ print("assertion fail: ", msg, "\n")
+ panic(1)
}
}
func main() {
- i5 := 5;
- i7 := 7;
+ i5 := 5
+ i7 := 7
+ hello := "hello"
switch true {
- case i5 < 5: assert(false, "<");
- case i5 == 5: assert(true, "!");
- case i5 > 5: assert(false, ">");
+ case i5 < 5:
+ assert(false, "<")
+ case i5 == 5:
+ assert(true, "!")
+ case i5 > 5:
+ assert(false, ">")
}
switch {
- case i5 < 5: assert(false, "<");
- case i5 == 5: assert(true, "!");
- case i5 > 5: assert(false, ">");
+ case i5 < 5:
+ assert(false, "<")
+ case i5 == 5:
+ assert(true, "!")
+ case i5 > 5:
+ assert(false, ">")
}
switch x := 5; true {
- case i5 < x: assert(false, "<");
- case i5 == x: assert(true, "!");
- case i5 > x: assert(false, ">");
+ case i5 < x:
+ assert(false, "<")
+ case i5 == x:
+ assert(true, "!")
+ case i5 > x:
+ assert(false, ">")
}
switch x := 5; true {
- case i5 < x: assert(false, "<");
- case i5 == x: assert(true, "!");
- case i5 > x: assert(false, ">");
+ case i5 < x:
+ assert(false, "<")
+ case i5 == x:
+ assert(true, "!")
+ case i5 > x:
+ assert(false, ">")
}
switch i5 {
- case 0: assert(false, "0");
- case 1: assert(false, "1");
- case 2: assert(false, "2");
- case 3: assert(false, "3");
- case 4: assert(false, "4");
- case 5: assert(true, "5");
- case 6: assert(false, "6");
- case 7: assert(false, "7");
- case 8: assert(false, "8");
- case 9: assert(false, "9");
- default: assert(false, "default");
+ case 0:
+ assert(false, "0")
+ case 1:
+ assert(false, "1")
+ case 2:
+ assert(false, "2")
+ case 3:
+ assert(false, "3")
+ case 4:
+ assert(false, "4")
+ case 5:
+ assert(true, "5")
+ case 6:
+ assert(false, "6")
+ case 7:
+ assert(false, "7")
+ case 8:
+ assert(false, "8")
+ case 9:
+ assert(false, "9")
+ default:
+ assert(false, "default")
}
switch i5 {
- case 0,1,2,3,4: assert(false, "4");
- case 5: assert(true, "5");
- case 6,7,8,9: assert(false, "9");
- default: assert(false, "default");
+ case 0, 1, 2, 3, 4:
+ assert(false, "4")
+ case 5:
+ assert(true, "5")
+ case 6, 7, 8, 9:
+ assert(false, "9")
+ default:
+ assert(false, "default")
}
switch i5 {
case 1:
case 2:
case 3:
- case 4: assert(false, "4");
- case 5: assert(true, "5");
+ case 4:
+ assert(false, "4")
+ case 5:
+ assert(true, "5")
case 6:
case 7:
case 8:
- case 9:
- default: assert(i5 == 5, "good");
+ case 9:
+ default:
+ assert(i5 == 5, "good")
}
switch i5 {
- case 0: dummy := 0; fallthrough;
- case 1: dummy := 0; fallthrough;
- case 2: dummy := 0; fallthrough;
- case 3: dummy := 0; fallthrough;
- case 4: dummy := 0; assert(false, "4");
- case 5: dummy := 0; fallthrough;
- case 6: dummy := 0; fallthrough;
- case 7: dummy := 0; fallthrough;
- case 8: dummy := 0; fallthrough;
- case 9: dummy := 0; fallthrough;
- default: dummy := 0; assert(i5 == 5, "good");
- }
-
- fired := 0; // BUG: should be able to use 'false'
+ case 0:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 1:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 2:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 3:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 4:
+ dummy := 0
+ _ = dummy
+ assert(false, "4")
+ case 5:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 6:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 7:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 8:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 9:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ default:
+ dummy := 0
+ _ = dummy
+ assert(i5 == 5, "good")
+ }
+
+ fired := false
switch i5 {
- case 0: dummy := 0; fallthrough; // tests scoping of cases
- case 1: dummy := 0; fallthrough;
- case 2: dummy := 0; fallthrough;
- case 3: dummy := 0; fallthrough;
- case 4: dummy := 0; assert(false, "4");
- case 5: dummy := 0; fallthrough;
- case 6: dummy := 0; fallthrough;
- case 7: dummy := 0; fallthrough;
- case 8: dummy := 0; fallthrough;
- case 9: dummy := 0; fallthrough;
- default: dummy := 0; fired = fired + 1; assert(i5 == 5, "good");
- }
- assert(fired > 0, "fired");
-
- count := 0;
+ case 0:
+ dummy := 0
+ _ = dummy
+ fallthrough // tests scoping of cases
+ case 1:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 2:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 3:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 4:
+ dummy := 0
+ _ = dummy
+ assert(false, "4")
+ case 5:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 6:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 7:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 8:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ case 9:
+ dummy := 0
+ _ = dummy
+ fallthrough
+ default:
+ dummy := 0
+ _ = dummy
+ fired = !fired
+ assert(i5 == 5, "good")
+ }
+ assert(fired, "fired")
+
+ count := 0
switch i5 {
- case 0: count = count + 1; fallthrough;
- case 1: count = count + 1; fallthrough;
- case 2: count = count + 1; fallthrough;
- case 3: count = count + 1; fallthrough;
- case 4: count = count + 1; assert(false, "4");
- case 5: count = count + 1; fallthrough;
- case 6: count = count + 1; fallthrough;
- case 7: count = count + 1; fallthrough;
- case 8: count = count + 1; fallthrough;
- case 9: count = count + 1; fallthrough;
- default: assert(i5 == count, "good");
- }
- assert(fired > 0, "fired");
-
- fired = 0;
+ case 0:
+ count = count + 1
+ fallthrough
+ case 1:
+ count = count + 1
+ fallthrough
+ case 2:
+ count = count + 1
+ fallthrough
+ case 3:
+ count = count + 1
+ fallthrough
+ case 4:
+ count = count + 1
+ assert(false, "4")
+ case 5:
+ count = count + 1
+ fallthrough
+ case 6:
+ count = count + 1
+ fallthrough
+ case 7:
+ count = count + 1
+ fallthrough
+ case 8:
+ count = count + 1
+ fallthrough
+ case 9:
+ count = count + 1
+ fallthrough
+ default:
+ assert(i5 == count, "good")
+ }
+ assert(fired, "fired")
+
+ switch hello {
+ case "wowie":
+ assert(false, "wowie")
+ case "hello":
+ assert(true, "hello")
+ case "jumpn":
+ assert(false, "jumpn")
+ default:
+ assert(false, "default")
+ }
+
+ fired = false
switch i := i5 + 2; i {
- case i7: fired = 1;
- default: assert(false, "fail");
+ case i7:
+ fired = true
+ default:
+ assert(false, "fail")
+ }
+ assert(fired, "var")
+
+ // switch on nil-only comparison types
+ switch f := func() {}; f {
+ case nil:
+ assert(false, "f should not be nil")
+ default:
+ }
+
+ switch m := make(map[int]int); m {
+ case nil:
+ assert(false, "m should not be nil")
+ default:
+ }
+
+ switch a := make([]int, 1); a {
+ case nil:
+ assert(false, "m should not be nil")
+ default:
+ }
+
+ // switch on interface.
+ switch i := interface{}("hello"); i {
+ case 42:
+ assert(false, `i should be "hello"`)
+ case "hello":
+ assert(true, "hello")
+ default:
+ assert(false, `i should be "hello"`)
+ }
+
+ // switch on implicit bool converted to interface
+ // was broken: see issue 3980
+ switch i := interface{}(true); {
+ case i:
+ assert(true, "true")
+ case false:
+ assert(false, "i should be true")
+ default:
+ assert(false, "i should be true")
+ }
+
+ // switch on interface with constant cases differing by type.
+ // was rejected by compiler: see issue 4781
+ type T int
+ type B bool
+ type F float64
+ type S string
+ switch i := interface{}(float64(1.0)); i {
+ case nil:
+ assert(false, "i should be float64(1.0)")
+ case (*int)(nil):
+ assert(false, "i should be float64(1.0)")
+ case 1:
+ assert(false, "i should be float64(1.0)")
+ case T(1):
+ assert(false, "i should be float64(1.0)")
+ case F(1.0):
+ assert(false, "i should be float64(1.0)")
+ case 1.0:
+ assert(true, "true")
+ case "hello":
+ assert(false, "i should be float64(1.0)")
+ case S("hello"):
+ assert(false, "i should be float64(1.0)")
+ case true, B(false):
+ assert(false, "i should be float64(1.0)")
+ case false, B(true):
+ assert(false, "i should be float64(1.0)")
+ }
+
+ // switch on array.
+ switch ar := [3]int{1, 2, 3}; ar {
+ case [3]int{1, 2, 3}:
+ assert(true, "[1 2 3]")
+ case [3]int{4, 5, 6}:
+ assert(false, "ar should be [1 2 3]")
+ default:
+ assert(false, "ar should be [1 2 3]")
+ }
+
+ // switch on channel
+ switch c1, c2 := make(chan int), make(chan int); c1 {
+ case nil:
+ assert(false, "c1 did not match itself")
+ case c2:
+ assert(false, "c1 did not match itself")
+ case c1:
+ assert(true, "chan")
+ default:
+ assert(false, "c1 did not match itself")
+ }
+
+ // empty switch
+ switch {
+ }
+
+ // empty switch with default case.
+ fired = false
+ switch {
+ default:
+ fired = true
+ }
+ assert(fired, "fail")
+
+ // Default and fallthrough.
+ count = 0
+ switch {
+ default:
+ count++
+ fallthrough
+ case false:
+ count++
+ }
+ assert(count == 2, "fail")
+
+ // fallthrough to default, which is not at end.
+ count = 0
+ switch i5 {
+ case 5:
+ count++
+ fallthrough
+ default:
+ count++
+ case 6:
+ count++
+ }
+ assert(count == 2, "fail")
+
+ i := 0
+ switch x := 5; {
+ case i < x:
+ os.Exit(0)
+ case i == x:
+ case i > x:
+ os.Exit(1)
+ }
+
+ // Unified IR converts the tag and all case values to empty
+ // interface, when any of the case values aren't assignable to the
+ // tag value's type. Make sure that `case nil:` compares against the
+ // tag type's nil value (i.e., `(*int)(nil)`), not nil interface
+ // (i.e., `any(nil)`).
+ switch (*int)(nil) {
+ case nil:
+ // ok
+ case any(nil):
+ assert(false, "case any(nil) matched")
+ default:
+ assert(false, "default matched")
}
- assert(fired == 1, "var");
}