在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
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\n", 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\n", 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类型的别名类型,它们本质上是同一个类型,只是类型名称不同,因此是无法通过编译的
|
请发表评论