golang笔记——流程控制
2016-02-25 16:49
351 查看
条件语句
if ... else if ... else 语句,如:
惯用法:if 语句条件前面可以前置一条初始化语句,而go语言中的函数可以返回多个值,有很多函数第二个返回值是 error 类型,则我们可以通过
循环语句
GO语言中的 switch 语句分为两种,一种是表达式 switch 语句,和其它语言中的 switch 使用方法相同;另一种是类型判断 switch 语句,它类似于类型断言,但使用 type 关键字来充当被判断的类型。
表达式 switch 示例如下:
类型判断 switch 语句示例如下:
此外,switch 语句还可以实现串联 if 语句的替代方案,可以使代码看起来更清晰易读,在 switch 表达式缺失的情况下, switch 判定目标会被视为布尔类型,第一个返回 true 的 case 表达式将会被执行,如:
for语句有三种用法,一是常规用法,结构先后是初始化子句、条件、后置子句,如:
二是类似其它语言中 while 的作用,注意GO语言中没有while语句,如:
而不使用任何条件则表示死循环:
三是类似其它语言中 foreach 的作用,用来迭代string\切片\字典等类型,如:
注意:if/for/switch 语句都可以接受一个可选的初始化子句; break\continue\goto 语句都可以跳转到指定标记,标记的定义使用 "标识符:" 的形式。
goto语句
goto语句只能配合标记来执行,跳转到指定位置,该语句在其它语言中很有争议,一般为了代码可读性都不推荐使用。
defer语句
GO语言特有的一个流程控制语句,它用来预定对一个函数的调用。它只能出现在一个函数中(假设是A函数),且只能调用另一个函数(假设是B函数),意味着在A函数结束返回时,延迟调用B函数,一般用于打开文件时的资源清理等工作。如果一个函数内部调用多个 defer 语句,则遵循后进先出的原则。defer 语句后面可以跟着匿名函数,来快速实现一些临时的功能。defer 调用的函数可以使用的变量,可以是通过参数传进来的,也可以是上下文中可以调用的变量,如果是传参进来的,则会立即被求值,如果是上下文中的变量,则不会立即被求值,而是取在 defer 函数调用时的值,这一点要注意。
异常处理语句
系统提供了一个 error 接口,定义如下:
GO中习惯使用 error 类型值来表明非正常的状态,但我们不需要自己去创建一个实现 error 接口的类型,而只需要通过 errors 包提供的 New 方法来创建,如: errors.New("this is error"); 我们来看一下 errors 的源代码:
可以直接把 error 类型值传递给 fmt.Print 方法参数,会自动检测并输出 error 类型值的 Error() 方法。
除了使用 erros.New 方法创建 error 类型值外,我们还可以使用 fmt.Errorf 函数来创建,它适合创建格式化字符串形式的 error类型值,注意这个方法并不会打印输出到屏幕,内部还是调用 errors.New 来实现的,如:
除了上面两种简便的创建 error 类型值的方法之外,我们也可以通过自定义实现 error 接口的方式来创建,比如 os.PathError 就是一个 error 接口的实现类型。查看 os/error.go 的源代码:
当遇到不可恢复的错误状态时,我们使用 panic 与 recover 来处理异常,这个异常就类似于其它语言中的异常了,而 error 相对而言只能算是一种状态码。
panic 接受一个做任意类型的函数(通常是 string 或 error 类型),然后停止当前的控制流程,将控制权交给调用它的函数,但调用它的函数的执行也将被停止,再继续向上传播。GO语言中使用 recover 来捕获这样的异常,它可以使当前的程序从异常状态中恢复并重新获得流程控制权,并返回 interface{} 类型。通常,我们在 defer 语句中调用一个匿名的函数,来进行 recover 处理(因为异常时虽然流程已经不可控,但 GO 保证 defer 语句会执行),可以通过 recover() 获取当前的异常,如果不为 nil,表示存在异常,且如果该异常是由GO语言运行时程序引起的,返回的将是 runtime.Error 类型的值。如:
如果一个函数里有多个 defer 语句,注意其执行顺序遵循先进后出的原则。
if ... else if ... else 语句,如:
if num > 100{ fmt.Println(">100") } else if 0 < 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 := "3" 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 > 100: log.Println(">100") case num < 0: log.Println("<0") default: log.Println("0<<num<<100") }
for语句有三种用法,一是常规用法,结构先后是初始化子句、条件、后置子句,如:
sum := 0 for i := 0; i < 100; i++ { sum += i }
二是类似其它语言中 while 的作用,注意GO语言中没有while语句,如:
i := 0 for i < 100 { i += 2 }
而不使用任何条件则表示死循环:
for { //... }
三是类似其它语言中 foreach 的作用,用来迭代string\切片\字典等类型,如:
m := map[string]int{"A": 1, "B": 2} for k, _ := range m { log.Print(k) }
注意:if/for/switch 语句都可以接受一个可选的初始化子句; break\continue\goto 语句都可以跳转到指定标记,标记的定义使用 "标识符:" 的形式。
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 语句,注意其执行顺序遵循先进后出的原则。
相关文章推荐
- GoogLeNet系列解读
- Google Guava 类库 笔记
- Django ~module index
- 【SPOJ-COINS】Bytelandian gold coins【DP】
- django的404,500错误自定义页面的配置
- [mongo] mongoose增删改查操作
- The backtracking algorithm
- Boyer-Moore Majority Vote Algorithm的更一般性问题
- Go Mobile 例子 audio 源码分析
- 原创翻译:James Whittaker系列——Google是如何测试的(2)
- 我的MVC框架————GothaMVC(4)GothamDispatcher的实现和Model层的封装
- sublime搭建基于GoSublime+gocode+MarGo的下载SublimeGO开发环境
- 我的MVC框架————GothaMVC(3)view层的实现
- [转]ionic $state.go passed $stateParams
- 我的MVC框架————GothaMVC(2)拦截器的实现
- hill descent algorithm
- this guy gonna be a daddy
- 我的MVC框架————GothaMVC(1)web容器和handler包装类
- POJ1389[Area of Simple Polygons]
- Algorithm 算法