[Go]条件语句

 1 package main
 2 
 3 import (
 4     "io/ioutil"
 5     "fmt"
 6 )
 7 
 8 //条件语句
 9 //if的条件语句不需要括号
10 //if的条件里可以赋值,if的条件里赋值的变量作用域就在这个if语句里
11 //switch会自动break,除非使用fallthrough
12 
13 func grade( score int ) string {
14     g := ""
15     switch  {  //switch里面可以没有表达式
16     case score < 0 || score >100:
17         panic(fmt.Sprintf( "Wrong score: %d", score) )  //中断程序执行,报错
18     case score < 60:
19         g = "F"
20     case score < 80:
21         g = "C"
22     case score < 90:
23         g ="B"
24     case score <= 100:
25         g ="A"
26     }
27     return g
28 }
29 
30 func main() {
31     const filename = "abc.txt"
32 /*  contents, err := ioutil.ReadFile(filename)
33     if err != nil {
34         fmt.Println(err)
35     }else {
36         fmt.Printf("%s
", contents)
37     }*/
38     //或者也可以用写成下面这样
39      if contents, err := ioutil.ReadFile(filename); err != nil{   //contents和err 定义在if里,生存期只在if里面才有
40          fmt.Println(err)  //open abc.txt: The system cannot find the file specified.
41      }else {
42          fmt.Printf("%s
", contents)
43      }
44 
45      fmt.Println(
46          grade( 0 ),  //F
47          grade( 59),  //F
48          grade( 99),  //A
49          grade(100),  //A
50      )
51 }

 

上面介绍了switch语句中switch表达式和case表达之间有着怎样的联系?

  switch表达式的结果值与某个case表达式中任意一个子表达式的结果值相等,该case表达式所属的case子句就会被选中,并且一旦某个case子句被选中,其中的附带在case表达式后边的那些语句就会被执行,同时其他的所以case子句都会被忽略(如果被选中的Case子句附带的语句列表中包含了fallthrough语句,那么紧挨在它下边的那个case子句附带的语句也会被执行) 

  正因为存在判断相等的操作,switch语句对switch表达式的结果类型,以及各个Case表达式中子表达式的结果类型都是有要求的(Go语言中,只有类型相同的值之间才有可能被允许进行判等操作)

    value1 := [...]int8{0, 1, 2, 3, 4, 5, 6}
    switch 1 + 3 { // 这条语句无法编译通过。
    case value1[0], value1[1]:
        fmt.Println("0 or 1")
    case value1[2], value1[3]:
        fmt.Println("2 or 3")
    case value1[4], value1[5], value1[6]:
        fmt.Println("4 or 5 or 6")
    }

  上面的代码中,1+3的求值结果是无类型的常量4,这个常量会被自动地转换为此种常量的默认类型的值,比如整数4的默认类型是int,浮点数3.14的默认类型是float64

  因此上面的switch表达式的结果类型是int,而那些case子表达式的结果类型却是int8,它们类型不同,是无法通过编译的

  再看下面这段代码的switch表达式的结果值是int8类型的,那些case表达式中的结果值是无类型的常量,却是可以编译的

    value2 := [...]int8{0, 1, 2, 3, 4, 5, 6}
    switch value2[4] {
    case 0, 1:
        fmt.Println("0 or 1")
    case 2, 3:
        fmt.Println("2 or 3")
    case 4, 5, 6:
        fmt.Println("4 or 5 or 6")

  这是因为如果case表达式中子表达式的结果值是无类型的常量,那么它的类型会被自动地转换为swicth表达式的结果类型,又由于上述那几个整数都可以被转换为int8类型的值么,所以对这些表达式的结果值进行判等操作是没有问题的

  即Swicth语句会进行有限的类型转换,但不能保证这种转换可以统一它们的类型

switch语句对它的case表达式还有哪些约束?

  1)switch语句不允许case表达式中的子表达式结果值存在相等的情况

    value3 := [...]int8{0, 1, 2, 3, 4, 5, 6}
    switch value3[4] { // 这条语句无法编译通过。
    case 0, 1, 2:
        fmt.Println("0 or 1 or 2")
    case 2, 3, 4:
        fmt.Println("2 or 3 or 4")
    case 4, 5, 6:
        fmt.Println("4 or 5 or 6")
    }

  但是这个约束只针对结果值为常量的子表达式,比如1+1和2不能同时出现。但是也就可以想办法绕过这个对子表达式的限制了,下面的代码就可以绕过限制

    value5 := [...]int8{0, 1, 2, 3, 4, 5, 6}
    switch value5[4] {
    case value5[0], value5[1], value5[2]:
        fmt.Println("0 or 1 or 2")
    case value5[2], value5[3], value5[4]:
        fmt.Println("2 or 3 or 4")
    case value5[4], value5[5], value5[6]:
        fmt.Println("4 or 5 or 6")
    }

  但是上面这种绕过方式对用于类型判断的switch语句无效,因为类型switch语句中的case表达式的子表达式必须直接由类型字面量表示,而无法通过间接的方式表示。

    value6 := interface{}(byte(127))
    switch t := value6.(type) { // 这条语句无法编译通过。
    case uint8, uint16:
        fmt.Println("uint8 or uint16")
    case byte:
        fmt.Printf("byte")
    default:
        fmt.Printf("unsupported type: %T", t)
    }

  这里byte是uint8类型的别名类型,它们本质上是同一个类型,只是类型名称不同,因此是无法通过编译的

在这个国度中,必须不停地奔跑,才能使你保持在原地。如果想要寻求突破,就要以两倍现在速度奔跑!
原文地址:https://www.cnblogs.com/yuxiaoba/p/9306597.html