Source file test/switch.go

     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 switch statements.
     8  
     9  package main
    10  
    11  import "os"
    12  
    13  func assert(cond bool, msg string) {
    14  	if !cond {
    15  		print("assertion fail: ", msg, "\n")
    16  		panic(1)
    17  	}
    18  }
    19  
    20  func main() {
    21  	i5 := 5
    22  	i7 := 7
    23  	hello := "hello"
    24  
    25  	switch true {
    26  	case i5 < 5:
    27  		assert(false, "<")
    28  	case i5 == 5:
    29  		assert(true, "!")
    30  	case i5 > 5:
    31  		assert(false, ">")
    32  	}
    33  
    34  	switch {
    35  	case i5 < 5:
    36  		assert(false, "<")
    37  	case i5 == 5:
    38  		assert(true, "!")
    39  	case i5 > 5:
    40  		assert(false, ">")
    41  	}
    42  
    43  	switch x := 5; true {
    44  	case i5 < x:
    45  		assert(false, "<")
    46  	case i5 == x:
    47  		assert(true, "!")
    48  	case i5 > x:
    49  		assert(false, ">")
    50  	}
    51  
    52  	switch x := 5; true {
    53  	case i5 < x:
    54  		assert(false, "<")
    55  	case i5 == x:
    56  		assert(true, "!")
    57  	case i5 > x:
    58  		assert(false, ">")
    59  	}
    60  
    61  	switch i5 {
    62  	case 0:
    63  		assert(false, "0")
    64  	case 1:
    65  		assert(false, "1")
    66  	case 2:
    67  		assert(false, "2")
    68  	case 3:
    69  		assert(false, "3")
    70  	case 4:
    71  		assert(false, "4")
    72  	case 5:
    73  		assert(true, "5")
    74  	case 6:
    75  		assert(false, "6")
    76  	case 7:
    77  		assert(false, "7")
    78  	case 8:
    79  		assert(false, "8")
    80  	case 9:
    81  		assert(false, "9")
    82  	default:
    83  		assert(false, "default")
    84  	}
    85  
    86  	switch i5 {
    87  	case 0, 1, 2, 3, 4:
    88  		assert(false, "4")
    89  	case 5:
    90  		assert(true, "5")
    91  	case 6, 7, 8, 9:
    92  		assert(false, "9")
    93  	default:
    94  		assert(false, "default")
    95  	}
    96  
    97  	switch i5 {
    98  	case 0:
    99  	case 1:
   100  	case 2:
   101  	case 3:
   102  	case 4:
   103  		assert(false, "4")
   104  	case 5:
   105  		assert(true, "5")
   106  	case 6:
   107  	case 7:
   108  	case 8:
   109  	case 9:
   110  	default:
   111  		assert(i5 == 5, "good")
   112  	}
   113  
   114  	switch i5 {
   115  	case 0:
   116  		dummy := 0
   117  		_ = dummy
   118  		fallthrough
   119  	case 1:
   120  		dummy := 0
   121  		_ = dummy
   122  		fallthrough
   123  	case 2:
   124  		dummy := 0
   125  		_ = dummy
   126  		fallthrough
   127  	case 3:
   128  		dummy := 0
   129  		_ = dummy
   130  		fallthrough
   131  	case 4:
   132  		dummy := 0
   133  		_ = dummy
   134  		assert(false, "4")
   135  	case 5:
   136  		dummy := 0
   137  		_ = dummy
   138  		fallthrough
   139  	case 6:
   140  		dummy := 0
   141  		_ = dummy
   142  		fallthrough
   143  	case 7:
   144  		dummy := 0
   145  		_ = dummy
   146  		fallthrough
   147  	case 8:
   148  		dummy := 0
   149  		_ = dummy
   150  		fallthrough
   151  	case 9:
   152  		dummy := 0
   153  		_ = dummy
   154  		fallthrough
   155  	default:
   156  		dummy := 0
   157  		_ = dummy
   158  		assert(i5 == 5, "good")
   159  	}
   160  
   161  	fired := false
   162  	switch i5 {
   163  	case 0:
   164  		dummy := 0
   165  		_ = dummy
   166  		fallthrough // tests scoping of cases
   167  	case 1:
   168  		dummy := 0
   169  		_ = dummy
   170  		fallthrough
   171  	case 2:
   172  		dummy := 0
   173  		_ = dummy
   174  		fallthrough
   175  	case 3:
   176  		dummy := 0
   177  		_ = dummy
   178  		fallthrough
   179  	case 4:
   180  		dummy := 0
   181  		_ = dummy
   182  		assert(false, "4")
   183  	case 5:
   184  		dummy := 0
   185  		_ = dummy
   186  		fallthrough
   187  	case 6:
   188  		dummy := 0
   189  		_ = dummy
   190  		fallthrough
   191  	case 7:
   192  		dummy := 0
   193  		_ = dummy
   194  		fallthrough
   195  	case 8:
   196  		dummy := 0
   197  		_ = dummy
   198  		fallthrough
   199  	case 9:
   200  		dummy := 0
   201  		_ = dummy
   202  		fallthrough
   203  	default:
   204  		dummy := 0
   205  		_ = dummy
   206  		fired = !fired
   207  		assert(i5 == 5, "good")
   208  	}
   209  	assert(fired, "fired")
   210  
   211  	count := 0
   212  	switch i5 {
   213  	case 0:
   214  		count = count + 1
   215  		fallthrough
   216  	case 1:
   217  		count = count + 1
   218  		fallthrough
   219  	case 2:
   220  		count = count + 1
   221  		fallthrough
   222  	case 3:
   223  		count = count + 1
   224  		fallthrough
   225  	case 4:
   226  		count = count + 1
   227  		assert(false, "4")
   228  	case 5:
   229  		count = count + 1
   230  		fallthrough
   231  	case 6:
   232  		count = count + 1
   233  		fallthrough
   234  	case 7:
   235  		count = count + 1
   236  		fallthrough
   237  	case 8:
   238  		count = count + 1
   239  		fallthrough
   240  	case 9:
   241  		count = count + 1
   242  		fallthrough
   243  	default:
   244  		assert(i5 == count, "good")
   245  	}
   246  	assert(fired, "fired")
   247  
   248  	switch hello {
   249  	case "wowie":
   250  		assert(false, "wowie")
   251  	case "hello":
   252  		assert(true, "hello")
   253  	case "jumpn":
   254  		assert(false, "jumpn")
   255  	default:
   256  		assert(false, "default")
   257  	}
   258  
   259  	fired = false
   260  	switch i := i5 + 2; i {
   261  	case i7:
   262  		fired = true
   263  	default:
   264  		assert(false, "fail")
   265  	}
   266  	assert(fired, "var")
   267  
   268  	// switch on nil-only comparison types
   269  	switch f := func() {}; f {
   270  	case nil:
   271  		assert(false, "f should not be nil")
   272  	default:
   273  	}
   274  
   275  	switch m := make(map[int]int); m {
   276  	case nil:
   277  		assert(false, "m should not be nil")
   278  	default:
   279  	}
   280  
   281  	switch a := make([]int, 1); a {
   282  	case nil:
   283  		assert(false, "m should not be nil")
   284  	default:
   285  	}
   286  
   287  	// switch on interface.
   288  	switch i := interface{}("hello"); i {
   289  	case 42:
   290  		assert(false, `i should be "hello"`)
   291  	case "hello":
   292  		assert(true, "hello")
   293  	default:
   294  		assert(false, `i should be "hello"`)
   295  	}
   296  
   297  	// switch on implicit bool converted to interface
   298  	// was broken: see issue 3980
   299  	switch i := interface{}(true); {
   300  	case i:
   301  		assert(true, "true")
   302  	case false:
   303  		assert(false, "i should be true")
   304  	default:
   305  		assert(false, "i should be true")
   306  	}
   307  
   308  	// switch on interface with constant cases differing by type.
   309  	// was rejected by compiler: see issue 4781
   310  	type T int
   311  	type B bool
   312  	type F float64
   313  	type S string
   314  	switch i := interface{}(float64(1.0)); i {
   315  	case nil:
   316  		assert(false, "i should be float64(1.0)")
   317  	case (*int)(nil):
   318  		assert(false, "i should be float64(1.0)")
   319  	case 1:
   320  		assert(false, "i should be float64(1.0)")
   321  	case T(1):
   322  		assert(false, "i should be float64(1.0)")
   323  	case F(1.0):
   324  		assert(false, "i should be float64(1.0)")
   325  	case 1.0:
   326  		assert(true, "true")
   327  	case "hello":
   328  		assert(false, "i should be float64(1.0)")
   329  	case S("hello"):
   330  		assert(false, "i should be float64(1.0)")
   331  	case true, B(false):
   332  		assert(false, "i should be float64(1.0)")
   333  	case false, B(true):
   334  		assert(false, "i should be float64(1.0)")
   335  	}
   336  
   337  	// switch on array.
   338  	switch ar := [3]int{1, 2, 3}; ar {
   339  	case [3]int{1, 2, 3}:
   340  		assert(true, "[1 2 3]")
   341  	case [3]int{4, 5, 6}:
   342  		assert(false, "ar should be [1 2 3]")
   343  	default:
   344  		assert(false, "ar should be [1 2 3]")
   345  	}
   346  
   347  	// switch on channel
   348  	switch c1, c2 := make(chan int), make(chan int); c1 {
   349  	case nil:
   350  		assert(false, "c1 did not match itself")
   351  	case c2:
   352  		assert(false, "c1 did not match itself")
   353  	case c1:
   354  		assert(true, "chan")
   355  	default:
   356  		assert(false, "c1 did not match itself")
   357  	}
   358  
   359  	// empty switch
   360  	switch {
   361  	}
   362  
   363  	// empty switch with default case.
   364  	fired = false
   365  	switch {
   366  	default:
   367  		fired = true
   368  	}
   369  	assert(fired, "fail")
   370  
   371  	// Default and fallthrough.
   372  	count = 0
   373  	switch {
   374  	default:
   375  		count++
   376  		fallthrough
   377  	case false:
   378  		count++
   379  	}
   380  	assert(count == 2, "fail")
   381  
   382  	// fallthrough to default, which is not at end.
   383  	count = 0
   384  	switch i5 {
   385  	case 5:
   386  		count++
   387  		fallthrough
   388  	default:
   389  		count++
   390  	case 6:
   391  		count++
   392  	}
   393  	assert(count == 2, "fail")
   394  
   395  	i := 0
   396  	switch x := 5; {
   397  	case i < x:
   398  		os.Exit(0)
   399  	case i == x:
   400  	case i > x:
   401  		os.Exit(1)
   402  	}
   403  
   404  	// Unified IR converts the tag and all case values to empty
   405  	// interface, when any of the case values aren't assignable to the
   406  	// tag value's type. Make sure that `case nil:` compares against the
   407  	// tag type's nil value (i.e., `(*int)(nil)`), not nil interface
   408  	// (i.e., `any(nil)`).
   409  	switch (*int)(nil) {
   410  	case nil:
   411  		// ok
   412  	case any(nil):
   413  		assert(false, "case any(nil) matched")
   414  	default:
   415  		assert(false, "default matched")
   416  	}
   417  }
   418  

View as plain text