update 2.2md,2.3md,fixed 8.1md code error
This commit is contained in:
22
2.3.md
22
2.3.md
@@ -1,11 +1,11 @@
|
||||
#2.3 流程和函数
|
||||
这小节我们要介绍Go里面的流程控制以及函数操作
|
||||
##流程控制
|
||||
流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的描述来表达很复杂的事情。
|
||||
流程控制在编程语言中是最伟大的发明了,因为有了它,你可以通过很简单的流程描述来表达很复杂的逻辑。流程控制包含分三大类:条件判断,循环控制和无条件跳转。
|
||||
###if
|
||||
`if`也许是所有语言中最常见的了,它的语法概括起来就是:`如果满足条件就做某事,否则做另一件事`
|
||||
`if`也许是各种编程语言中最常见的了,它的语法概括起来就是:`如果满足条件就做某事,否则做另一件事`
|
||||
|
||||
Go里面`if`条件语法中不需要括号,如下代码所示
|
||||
Go里面`if`条件判断语句中不需要括号,如下代码所示
|
||||
|
||||
if x > 10 {
|
||||
fmt.Println("x is greater than 10")
|
||||
@@ -13,7 +13,7 @@ Go里面`if`条件语法中不需要括号,如下代码所示
|
||||
fmt.Println("x is less than 10")
|
||||
}
|
||||
|
||||
Go的`if`还有一个强大的地方就是条件里面允许声明一个变量,这个变量的作用域只能在该条件中,出了这个条件就不起作用了,如下所示
|
||||
Go的`if`还有一个强大的地方就是条件判断语句里面允许声明一个变量,这个变量的作用域只能在该条件逻辑块内,其他地方就不起作用了,如下所示
|
||||
|
||||
// 计算获取值x,然后根据x返回的大小,判断是否大于10。
|
||||
if x := computedValue(); x > 10 {
|
||||
@@ -37,7 +37,7 @@ Go的`if`还有一个强大的地方就是条件里面允许声明一个变量
|
||||
|
||||
###goto
|
||||
|
||||
Go有`goto`语句——请明智地使用它。用`goto`跳转到一定是当前函数内定义的标签。例如假设这样一个循环:
|
||||
Go有`goto`语句——请明智地使用它。用`goto`跳转到必须在当前函数内定义的标签。例如假设这样一个循环:
|
||||
|
||||
func myFunc() {
|
||||
i := 0
|
||||
@@ -47,7 +47,7 @@ Go有`goto`语句——请明智地使用它。用`goto`跳转到一定是当前
|
||||
goto Here //跳转到Here去
|
||||
}
|
||||
|
||||
标签名是大小写敏感的。
|
||||
>标签名是大小写敏感的。
|
||||
|
||||
###for
|
||||
Go里面最强大的一个控制逻辑就是`for`,它即可以用来循环读取数据,又可以当作`while`来控制逻辑,还能迭代操作。它的语法如下:
|
||||
@@ -56,7 +56,7 @@ Go里面最强大的一个控制逻辑就是`for`,它即可以用来循环读
|
||||
//...
|
||||
}
|
||||
|
||||
`expression1`、`expression2`和`expression3`都是表达式,其中`expression1`和`expression3`是变量声明或者函数调用返回值之类的,`expression2`是条件判断,`expression1`在循环开始之前调用,`expression3`在每轮循环结束之时调用。
|
||||
`expression1`、`expression2`和`expression3`都是表达式,其中`expression1`和`expression3`是变量声明或者函数调用返回值之类的,`expression2`是用来条件判断,`expression1`在循环开始之前调用,`expression3`在每轮循环结束之时调用。
|
||||
|
||||
一个例子比上面讲那么多更有用,那么我们看看下面的例子吧:
|
||||
|
||||
@@ -224,7 +224,7 @@ Go里面最强大的一个控制逻辑就是`for`,它即可以用来循环读
|
||||
上面这个里面我们可以看到`max`函数有两个参数,它们的类型都是`int`,那么第一个变量的类型可以省略(即 a,b int,而非 a int, b int),默认为离它最近的类型,同理多于2个同类型的变量或者返回值。同时我们注意到它的返回值就是一个类型,这个就是省略写法。
|
||||
|
||||
###多个返回值
|
||||
Go语言和C相比,更先进的地方,其中一点就是能够返回多个值,也许这个思想来源于Python。
|
||||
Go语言比C更先进的特性,其中一点就是函数能够返回多个值。
|
||||
|
||||
我们直接上代码看例子
|
||||
|
||||
@@ -246,7 +246,7 @@ Go语言和C相比,更先进的地方,其中一点就是能够返回多个
|
||||
fmt.Printf("%d * %d = %d\n", x, y, xTIMESy)
|
||||
}
|
||||
|
||||
上面的例子我们可以看到直接返回了两个参数,当然我们也可以命名返回参数的变量,这个例子里面只是用了两个类型,我们也可以改成如下这样的定义,然后返回的时候不用带上变量名,因为直接在函数里面初始化了。但如果你的函数是导出的(首字母大写),官方建议,最好命名返回值,因为不命名返回值,虽然使得代码更加简洁了,但是会造成生成的文档不易读。
|
||||
上面的例子我们可以看到直接返回了两个参数,当然我们也可以命名返回参数的变量,这个例子里面只是用了两个类型,我们也可以改成如下这样的定义,然后返回的时候不用带上变量名,因为直接在函数里面初始化了。但如果你的函数是导出的(首字母大写),官方建议:最好命名返回值,因为不命名返回值,虽然使得代码更加简洁了,但是会造成生成的文档可读性差。
|
||||
|
||||
func SumAndProduct(A, B int) (add int, Multiplied int) {
|
||||
add = A+B
|
||||
@@ -265,7 +265,7 @@ Go函数支持变参。接受变参的函数是有着不定数量的参数的。
|
||||
}
|
||||
|
||||
###传值与传指针
|
||||
当我们传一个参数值到被调用函数里面时,实际上是传了这个值的一份copy,当在被调用函数中修改参数值的时候,调用函数中相应实参不会发生任何变化,因为我们作用在了copy上面。
|
||||
当我们传一个参数值到被调用函数里面时,实际上是传了这个值的一份copy,当在被调用函数中修改参数值的时候,调用函数中相应实参不会发生任何变化,因为数值变化只作用在copy上。
|
||||
|
||||
为了验证我们上面的说法,我们来看一个例子
|
||||
|
||||
@@ -320,7 +320,7 @@ Go函数支持变参。接受变参的函数是有着不定数量的参数的。
|
||||
这样,我们就达到了修改`x`的目的。那么到底传指针有什么好处呢?
|
||||
|
||||
- 传指针使得多个函数能操作同一个对象。
|
||||
- 传指针比较轻量级 (8 bytes)只是传内存地址,我们可以通过指针高效的传递大的结构体。如果传值的话,那么每次传递, 在copy上面就会花费大量的时间和内存。所以记住了,当你要传递大的结构体的时候,用指针是一个明智的选择。
|
||||
- 传指针比较轻量级 (8bytes),只是传内存地址,我们可以用指针传递体积大的结构体。如果用参数值传递的话, 在每次copy上面就会花费相对较多的系统开销(内存和时间)。所以当你要传递大的结构体的时候,用指针是一个明智的选择。
|
||||
- Go语言中`string`,`slice`,`map`这三种类型的实现机制类似指针,所以可以直接传递,而不用取地址后传递指针。(注:若函数需改变`slice`的长度,则仍需要取地址传递指针)
|
||||
|
||||
###defer
|
||||
|
||||
Reference in New Issue
Block a user