golang笔记——流程控制
条件语句
if ... else if ... else 语句,如:
if num > {
fmt.Println(">100")
} else if < num {
fmt.Println("<0")
} else {
fmt.Println("0<<num<<100")
}
惯用法:if 语句条件前面可以前置一条初始化语句,而go语言中的函数可以返回多个值,有很多函数第二个返回值是 error 类型,则我们可以通过
if v, err := func(); err == nil {
//逻辑语句
}
循环语句
GO语言中的 switch 语句分为两种,一种是表达式 switch 语句,和其它语言中的 switch 使用方法相同;另一种是类型判断 switch 语句,它类似于类型断言,但使用 type 关键字来充当被判断的类型。
表达式 switch 示例如下:
//表达式 switch
switch content := getContent(); content {
default:
fmt.Println("Unknow language")
case "Lua":
break
case "Python":
fmt.Println("python")
case "C", "C++", "Java":
fmt.Println("A compiled language")
}
类型判断 switch 语句示例如下:
v := ""
switch interface{}(v).(type) {
case string:
log.Printf("Thie string is '%s'.\n", v)
case int, uint, int8, uint8, int16, uint16:
log.Printf("Thie integer is %d.\n", v)
default:
log.Printf("Unsupported value.(type=%T)\n", v)
}
此外,switch 语句还可以实现串联 if 语句的替代方案,可以使代码看起来更清晰易读,在 switch 表达式缺失的情况下, switch 判定目标会被视为布尔类型,第一个返回 true 的 case 表达式将会被执行,如:
switch {
case num > :
log.Println(">100")
case num < :
log.Println("<0")
default:
log.Println("0<<num<<100")
}
再此外,switch 的 case 语句最后一行可以加上 fallthrough,表示继续执行下一个case(不需要匹配条件表达式),这个有什么作用呢?猜想可能在某个顺序工作流中,比如根据一个status的值,依次执行某些动作,如果每个case最后都有这个 fallthrough,那么无论当前 status 是多少,都能保证执行完剩下的动作。注意,fallthrough必须要放在 case块的结尾,且如果前面有 break,将不会执行。(break就提前结束了本次case了,这个可没有 defer 的效果)
for语句有三种用法,一是常规用法,结构先后是初始化子句、条件、后置子句,如:
sum :=
for i := ; i < ; i++ {
sum += i
}
二是类似其它语言中 while 的作用,注意GO语言中没有while语句,如:
i :=
for i < {
i +=
}
而不使用任何条件则表示死循环:
for {
//...
}
三是类似其它语言中 foreach 的作用,用来迭代string\切片\字典等类型,如:
m := map[string]int{"A": , "B": }
for k, _ := range m {
log.Print(k)
}
注意:if/for/switch 语句都可以接受一个可选的初始化子句; break\continue\goto 语句都可以跳转到指定标记,标记的定义使用 "标识符:" 的形式。
for ... range 语句本身是只读的,如下面的代码是不会改变原数据的:
m := make(map[string]int)
m["a"] =
m["b"] =
for _, v := range m {
v = v *
}
for _, v := range m {
println(v)
} s := []int{, }
s[] =
s[] =
for _, v := range s {
v = v *
}
for _, v := range s {
println(v)
}
但是,如果 v 本身就是指针,那自然还是能修改的,或者对于切片和字典来说,通过 for ... range 的索引或键来修改都是可行的。
也可以对一个函数进行 range (当然前提是这个函数返回值是可 range的类型,如字典切片等),函数只会被调用一次:
for userid, user range manager.GetUserManager().GetOnlineUserMap {
println(userid)
}
goto语句
goto语句只能配合标记来执行,跳转到指定位置,该语句在其它语言中很有争议,一般为了代码可读性都不推荐使用。
defer语句
GO语言特有的一个流程控制语句,它用来预定对一个函数的调用。它只能出现在一个函数中(假设是A函数),且只能调用另一个函数(假设是B函数),意味着在A函数结束返回时,延迟调用B函数,一般用于打开文件时的资源清理等工作。如果一个函数内部调用多个 defer 语句,则遵循后进先出的原则。defer 语句后面可以跟着匿名函数,来快速实现一些临时的功能。defer 调用的函数可以使用的变量,可以是通过参数传进来的,也可以是上下文中可以调用的变量,如果是传参进来的,则会立即被求值,如果是上下文中的变量,则不会立即被求值,而是取在 defer 函数调用时的值,这一点要注意。
异常处理语句
系统提供了一个 error 接口,定义如下:
type error interface {
Error() string
}
GO中习惯使用 error 类型值来表明非正常的状态,但我们不需要自己去创建一个实现 error 接口的类型,而只需要通过 errors 包提供的 New 方法来创建,如: errors.New("this is error"); 我们来看一下 errors 的源代码:
package errors func New(text string) error {
return &errorString{text}
} type errorString struct {
s string
} func (e *errorString) Error() string {
return e.s
}
可以直接把 error 类型值传递给 fmt.Print 方法参数,会自动检测并输出 error 类型值的 Error() 方法。
除了使用 erros.New 方法创建 error 类型值外,我们还可以使用 fmt.Errorf 函数来创建,它适合创建格式化字符串形式的 error类型值,注意这个方法并不会打印输出到屏幕,内部还是调用 errors.New 来实现的,如:
err := fmt.Errorf("%s\n", "nil error!")
除了上面两种简便的创建 error 类型值的方法之外,我们也可以通过自定义实现 error 接口的方式来创建,比如 os.PathError 就是一个 error 接口的实现类型。查看 os/error.go 的源代码:
type PathError struct {
Op string
Path string
Err error
} func (e *PathError) Error() string { return e.Op + " " + e.Path + ": " + e.Err.Error() }
当遇到不可恢复的错误状态时,我们使用 panic 与 recover 来处理异常,这个异常就类似于其它语言中的异常了,而 error 相对而言只能算是一种状态码。
panic 接受一个做任意类型的函数(通常是 string 或 error 类型),然后停止当前的控制流程,将控制权交给调用它的函数,但调用它的函数的执行也将被停止,再继续向上传播。GO语言中使用 recover 来捕获这样的异常,它可以使当前的程序从异常状态中恢复并重新获得流程控制权,并返回 interface{} 类型。通常,我们在 defer 语句中调用一个匿名的函数,来进行 recover 处理(因为异常时虽然流程已经不可控,但 GO 保证 defer 语句会执行),可以通过 recover() 获取当前的异常,如果不为 nil,表示存在异常,且如果该异常是由GO语言运行时程序引起的,返回的将是 runtime.Error 类型的值。如:
defer func() {
if r := recover(); r != nil {
fmt.Printf("Recoverd panic:%s\n", r)
}
}()
如果一个函数里有多个 defer 语句,注意其执行顺序遵循先进后出的原则。
golang笔记——流程控制的更多相关文章
- Golang的流程控制
流程控制 条件语句 例: var b bool = true if b{ fmt.Print("b是True") }else{ fmt.Print("b是false&qu ...
- JavaScript学习笔记——流程控制
javascript流程控制流程:就是程序代码的执行顺序.流程控制:通过规定的语句让程序代码有条件的按照一定的方式执行. 一.顺序结构 按照书写顺序来执行,是程序中最基本的流程结构. 二.选择结构(分 ...
- Go语言学习笔记-流程控制(二)
Go语言流程控制 字典类型Map 1.上节遗留:map字典类型 变量声明:var myMap map[string] PersonInfo 其中,myMap是变量名,string是键的类型,Perso ...
- golang之流程控制(注意点)
Go在流程控制方面特点如下: 没有do和while循环,只有一个广义的for语句 switch语句灵活多变,还可以用于类型判断 if语句和switch语句都可以包含一条初始化子语句 break语句和c ...
- [golang note] 流程控制
流程控制 • 流程控制语句作用 ▪ 选择:根据条件跳转到不同的执行序列. ▪ 循环:根据条件反复执行某个序列. ▪ 跳转:据条件返回到某执行序列. • 流程控制语句类型 ▪ 条件语句:关键字为if.e ...
- go学习笔记-流程控制(if/else,for/range)
流程控制(if/else,for/range) if if条件判断语句的语法概括起来就是:如果满足条件就做某事,否则做另一件事. func testIf() { num := 10 if num &l ...
- python学习笔记---流程控制
二.流程控制 2.1选择结构与语句 2.1.1 最简单的if语句 注意:if语句后边必须加上冒号 满足条件后.可以执行多条语句. #最简单的if语句 print("请输入一个既能整除2,又能 ...
- Java学习笔记-流程控制
在Java中,最常见的就是顺序结构,另外,还有其他的一些的结构,选择,循环等,这些程序结构的加入,使得程序代码更有选择性 判断结构 if语句 三种格式: if(条件表达式) { 执行语句; } if( ...
- Go笔记-流程控制
[if] if 是用于测试某个条件的语句,如果该条件(逻辑型或布尔型)成立,则会执行大括号内的代码,第一个大括号必须和if 或者else同行,否则非法 // 方式1 if condition { // ...
随机推荐
- 【小白的CFD之旅】08 CFD速成之道
学了那么一个星期的流体力学,又看了一周的计算流体力学,小白对于如何应用CFD解决工程流体问题,依然是一无所知.眼看一个月的时间已经过半,小白有点着急起来.于是在一个阳光明媚的早晨,小白又找到了黄师姐. ...
- BZOJ 2120 数颜色&2453 维护队列 [带修改的莫队算法]【学习笔记】
2120: 数颜色 Time Limit: 6 Sec Memory Limit: 259 MBSubmit: 3665 Solved: 1422[Submit][Status][Discuss] ...
- Vijos1006P1006晴天小猪历险记之Hill[最短路]
P1006晴天小猪历险记之Hill Accepted 标签:晴天小猪历险记[显示标签] 背景 在很久很久以前,有一个动物村庄,那里是猪的乐园(^_^),村民们勤劳.勇敢.善良.团结……不过有一 ...
- python-异常处理
一.异常 异常是什么? 就是影响程序正常执行的事件,异常在程序执行的过程中发生,脚本发生异常时,我们需要捕获它,否则程序就会终止. 异常处理: 1.捕获异常:try:...except ..... w ...
- StackExchange.Redis 使用-配置
Configurationredis有很多不同的方法来配置连接字符串 , StackExchange.Redis 提供了一个丰富的配置模型,当调用Connect 或者 ConnectAsync 时需要 ...
- ubuntu14.04下简易二进制安装mysql
下载mysql-commnunity的5.6.24通用二进制版 tar解压 我安装到/opt目录,所以mv到/opt/ 可选,建了个软链 ln -s *** mysql 添加运行mysql服务的用户和 ...
- 【笔记6】用pandas实现条目数据格式的推荐算法 (基于物品的协同)
''' 基于物品的协同推荐 矩阵数据 说明: 1.修正的余弦相似度是一种基于模型的协同过滤算法.我们前面提过,这种算法的优势之 一是扩展性好,对于大数据量而言,运算速度快.占用内存少. 2.用户的评价 ...
- image的加载事件(onload)和加载状态(complete)
之前做过这样一个需求,要让商家页的商家图片按照图片外面box的大小等比例缩放.之前的想法是在页面中先输出图片的src,然后在页面底部初始化js,然后在js中写相应的可以使图片按照box的大小等比例缩放 ...
- Dell xps 13 9350待机时总是关机的处理方法
现象: 年初买的dell xps13 9350,最近可能是由于win10做了一些更新,每次睡眠就自动关机了,重启很多次,修改电源选项都没用, 原因分析: 在网上搜了一下,有人发现xps15 9350也 ...
- sql语句 in的教训
如果子查询条件数据量特别大的话,千万不要用子查询.