0
点赞
收藏
分享

微信扫一扫

第6关 条件语句和循环语句


千万别给自己的懒惰

找借口

千万别给自己的愚昧

找理由

千万别给自己的无知

找台阶

——实干《实干日记》


第6关 条件语句和循环语句

  • ​​6-1 if条件控制语句​​
  • ​​6-2 go语言的for循环​​
  • ​​6-3 go语言的for range用法​​
  • ​​6-4 goto语句能帮我们完成什么功能?​​
  • ​​6-5 switch语句能让代码可读性更高​​
  • ​​6-6 python中如何实现switch的效果?​​

6-1 if条件控制语句

实例代码:【着重看简化写法,还有if语句代码块的变量的作用域】

package main

import "fmt"

func main(){
// if 语句
num := 12
if num % 2 == 0{
fmt.Println("偶数") // 偶数

}else {
fmt.Println("奇数")
}

score := 99
if score >= 90 {
fmt.Println("优秀") // 优秀
}else if score >=60{
fmt.Println("一般")
}else {
fmt.Println("不合格")
}

// 简化写法 if statement;condition
if age :=18;age % 2 == 0{
fmt.Println("偶数") // 偶数

}else{
fmt.Println(age)
}
//fmt.Println(age) // undefined: age 因为age的作用域在if代码块里
}

6-2 go语言的for循环

示例代码如下:

package main

import "fmt"

func main(){
// for init;condition;post{} 计算 1-10的和
sum := 0
for i:=1;i<=10;i++{
sum += i
} // i 是局部变量
fmt.Println(sum) // 55
// for 循环执行逻辑
//1.只执行1次 i:=1
//2.判断i<=10
//3.sum+=1,此时sum=0+1=1
//4.执行i++,此时i=1+1=2

//5.判断i<=10
//6.执行sum+=i,此时sum=1+2=3
//7.执行i++,此时i=2+1=3

// 死循环
//for {
// fmt.Println("die for loop")
//}

// 注意一下三种写法
j := 0
for j <= 9 {
fmt.Println(j)
j++
}
for ;j <= 9; {
fmt.Println(j)
j++
}
for ;j <= 9; j++{
fmt.Println(j)
}
}

6-3 go语言的for range用法

示例代码1:

package main

import "fmt"

func main(){
// 循环字符串
name := "keegan"
//for index,value := range name{
// // value为什么是数字?ascii值
// //fmt.Println(index,value)
// // 格式化输出,打印index和value
// fmt.Printf("index:%d,value:%c\n",index,value)
//}
/*
0 107
1 101
2 101
3 103
4 97
5 110
*/
/*
index:0,value:k
index:1,value:e
index:2,value:e
index:3,value:g
index:4,value:a
index:5,value:n
*/
for _,value := range name{
// value为什么是数字?ascii值
//fmt.Println(index,value)
// 格式化输出,只打印value的值
fmt.Printf("%c\n",value)
}
/*
k
e
e
g
a
n
*/
// 1.name是一个字符串 2.字符串是一个字符数组,索引取值
}

示例代码2:【问题来了】

package main

import "fmt"

func main(){
// 循环字符串
name := "keegan:代码写注释"
fmt.Printf("%c\n",name[0])
fmt.Printf("%c\n",name[7])
/*
k
ä
*/
}

我们期望的输出结果是:

k

然而实际输出结果是:

k

ä

why呢?

utf-8编码问题,用rune处理。

这个时候怎么办?

第五关讲过,统一转成rune。

import "fmt"

func main(){
// 循环字符串
name := "keegan:代码写注释"
name_arr := []rune(name)
for i := 0;i<len(name_arr);i++{
fmt.Printf("%c\n",name_arr[i])
}
}

/*输出结果:
k
e
e
g
a
n
:





*/

在字符串遍历的时候,尽量使用range。

对于含有中文的字符串遍历的乱码问题,统一转成rune数组。然后对数组遍历。

package main

import "fmt"

func main(){
// 循环字符串
name := "keegan:代码写注释"
name_arr := []rune(name)
for _,value := range(name_arr){
fmt.Printf("%c\n",value)
}
}
/*输出结果:
k
e
e
g
a
n
:





*/

6-4 goto语句能帮我们完成什么功能?

看定义:

Go 语言的 goto 语句可以无条件地转移到过程中指定的行。

goto 语句通常与条件语句配合使用。可用来实现条件转移, 构成循环,跳出循环体等功能。

但是,在结构化程序设计中一般不主张使用 goto 语句, 以免造成程序流程的混乱,使理解和调试程序都产生困难。

能不用就不用。

第6关 条件语句和循环语句_条件语句 循环语句

看代码:

小试牛刀:

package main

import "fmt"

func main() {
// 定义局部变量
var a int = 10

// 循环效果:跳出15的打印。【就是不打印15,打印其他的东西】
LOOP:for a < 20{
// 如果等于15
if a == 15 {
// 累加器
a++
// 跳出循环 执行LOOP对应的语句,执行下一次循环
goto LOOP
// 这里的循环效果还可以用continue和break来实现
}
// 如果不等于15就正常打印
fmt.Printf("a的值为:%d\n",a)
a++
}
}

应用场景:使用goto退出多层循环

package main
import "fmt"
func main() {
var breakAgain bool
// 外循环
for x := 0; x < 10; x++ {
// 内循环
for y := 0; y < 10; y++ {
// 满足某个条件时, 退出循环
if y == 2 {
// 设置退出标记
breakAgain = true
// 退出本次循环
break
}
}
// 根据标记, 还需要退出一次循环
if breakAgain {
break
}
}
fmt.Println("done")
}
/*输出结果
done
*/

优化后:

package main
import "fmt"
func main() {
for x := 0; x < 10; x++ {
for y := 0; y < 10; y++ {
if y == 2 {
// 跳转到标签
goto breakHere
}
}
}
// 手动返回, 避免执行进入标签
return
// 标签
breakHere:
fmt.Println("done")
}
/*输出结果
done
*/

秀的一批,蒂花之秀~

应用场景:使用goto集中处理错误

多处错误处理存在代码重复时是非常棘手的,例如:

package main
import "fmt"
func main() {
err := firstCheckError()
if err != nil {
// 代码重复,同样逻辑
fmt.Println(err)
exitProcess()
return
}
err = secondCheckError()
if err != nil {
// 代码重复,同样逻辑
fmt.Println(err)
exitProcess()
return
}
fmt.Println("done")
}

上述代码修改一下:【goto处理】

package main
import "fmt"
func main() {
err := firstCheckError()
if err != nil {
goto onExit
}
err = secondCheckError()
if err != nil {
goto onExit
}
fmt.Println("done")
return
onExit:
fmt.Println(err)
exitProcess()
}

goto语句能不用就不用,写的爽,维护的麻烦。因为代码执行的逻辑一般都是自顶向下的【大家都习惯了】,一行一行执行的,最容易维护。

6-5 switch语句能让代码可读性更高

来看这样的代码:

package main

import "fmt"

func main(){
score := 75
grade := "A"

if score >= 90{
grade = "A"
}else if 80 <= score && score <= 89{
grade = "B"
}else if 70 <= score && score <= 79{
grade = "C"
}else if 60 <= score && score <= 69 {
grade = "D"
}else {
grade = "E"
}
fmt.Println(grade) // C
}

大量的if-else if分支语句看起来并不是很优雅。

用switch处理之后:

package main

import "fmt"

func main() {
/* 定义局部变量 */
score := 99
grade := "A"

switch {
case score >= 90: grade = "A"
case 80 <= score && score <= 89: grade = "B"
case 70 <= score && score <= 79: grade = "C"
case 60 <= score && score <= 69: grade = "D"
default: grade = "E"
}
fmt.Printf("你的等级是 %s\n", grade ); // 你的等级是 A
}

上述代码默认有break效果的。【跟c语言用法一样的】

如果不想break,像第1个case执行完之后接着执行第2个case … 一直执行到default语句然后退出switch语句 怎么做?

用fallthrough

package main

import "fmt"

func main() {
/* 定义局部变量 */
score := 99
grade := "A"

switch {
case score >= 90: grade = "A";fallthrough
case 80 <= score && score <= 89: grade = "B"
case 70 <= score && score <= 79: grade = "C"
case 60 <= score && score <= 69: grade = "D"
default: grade = "E"
}
fmt.Printf("你的等级是 %s\n", grade ); // 你的等级是 B
}

执行到 score >= 90的时候,score := 99符合该case,但是加了fallthrough,继续往下走,

执行到80 <= score && score <= 89,此时grade= “B”,默认有break效果,退出switch语句,执行Printf输出语句,

输出 你的等级是 B

现在加点东西,对分数判断,是打印优秀,还是打印良好?【不需要加fallthrough,不合逻辑】

package main

import "fmt"

func main() {
/* 定义局部变量 */
score := 9
grade := "A"

switch {
case score >= 90:
grade = "A";
fmt.Println("优秀");
case 80 <= score && score <= 89:
grade = "B";
fmt.Println("良好")
case 70 <= score && score <= 79:
grade = "C";
fmt.Println("中等")
case 60 <= score && score <= 69:
grade = "D";
fmt.Println("合格")
default:
grade = "E";
fmt.Println("请准备补考")
}
fmt.Printf("你的等级是 %s\n", grade ); // 你的等级是 A
}

再来看一个case满足多种情况的输出:

package main

import "fmt"

func main() {
/* 定义局部变量 */
var grade string = "B"
var marks int = 60

switch marks {
case 90: grade = "A"
case 80: grade = "B"
// 一个case满足多种情况.即一分支多值
case 70,60:grade = "C";fmt.Println("都是合格")
default: grade = "D"
}
fmt.Printf("你的等级是 %s\n", grade ); // 你的等级是 C
}

6-6 python中如何实现switch的效果?

查看Python官方:PEP 3103-A Switch/Case Statement

发现其实实现Switch Case需要被判断的变量是可哈希的和可比较的,这与Python倡导的灵活性有冲突。在实现上,优化不好做,可能到最后最差的情况汇编出来跟If Else组是一样的。所以Python没有支持。

但是,也可以实现类似switch的效果:

# https://www.python.org/dev/peps/pep-3103/

score = 90
switch = {
90: lambda : print("A"),
80: lambda : print("B"),
70: lambda : print("C"),
}

switch[score]() # A

以下代码仅供参考:

class switch(object):
def __init__(self, value):
self.value = value
self.fall = False

def __iter__(self):
"""Return the match method once, then stop"""
yield self.match
raise StopIteration

def match(self, *args):
"""Indicate whether or not to enter a case suite"""
if self.fall or not args:
return True
elif self.value in args: # changed for v1.5, see below
self.fall = True
return True
else:
return False

# The following example is pretty much the exact use-case of a dictionary,
# but is included for its simplicity. Note that you can include statements
# in each suite.
v = 'ten'
for case in switch(v):
if case('one'):
print 1
break
if case('two'):
print 2
break
if case('ten'):
print 10
break
if case('eleven'):
print 11
break
if case(): # default, could also just omit condition or 'if True'
print "something else!"
# No need to break here, it'll stop anyway

# break is used here to look as much like the real thing as possible, but
# elif is generally just as good and more concise.

# Empty suites are considered syntax errors, so intentional fall-throughs
# should contain 'pass'
c = 'z'
for case in switch(c):
if case('a'): pass # only necessary if the rest of the suite is empty
if case('b'): pass
# ...
if case('y'): pass
if case('z'):
print "c is lowercase!"
break
if case('A'): pass
# ...
if case('Z'):
print "c is uppercase!"
break
if case(): # default
print "I dunno what c was!"

# As suggested by Pierre Quentel, you can even expand upon the
# functionality of the classic 'case' statement by matching multiple
# cases in a single shot. This greatly benefits operations such as the
# uppercase/lowercase example above:
import string
c = 'A'
for case in switch(c):
if case(*string.lowercase): # note the * for unpacking as arguments
print "c is lowercase!"
break
if case(*string.uppercase):
print "c is uppercase!"
break
if case('!', '?', '.'): # normal argument passing style also applies
print "c is a sentence terminator!"
break
if case(): # default
print "I dunno what c was!"

# Since Pierre's suggestion is backward-compatible with the original recipe,
# I have made the necessary modification to allow for the above usage.



举报

相关推荐

0 条评论