mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-11 22:53:43 +08:00
06.2
This commit is contained in:
@@ -9,7 +9,7 @@
|
|||||||
|
|
||||||
## 翻译进度
|
## 翻译进度
|
||||||
|
|
||||||
6.1 [介绍](eBook/6.1.md)
|
6.2 [参数与返回值](eBook/06.2.md)
|
||||||
|
|
||||||
## 支持本书
|
## 支持本书
|
||||||
|
|
||||||
|
@@ -1,24 +1,8 @@
|
|||||||
## 啊哦,亲,你看得也太快了。。。还没翻译完呢 0 0
|
# 6.2 函数参数与返回值
|
||||||
|
|
||||||
要不等到 **2014 年 7 月 9 日** 再来看看吧~~
|
函数能够接收参数供自己使用,也可以返回零个或多个值(我们通常把返回多个值称为返回一组值)。相比与C、C++、Java和C#,多值返回是Go的一大特性,为我们判断一个函数是否正常执行(参考[第 5.2 节](05.2.md))提供了方便。
|
||||||
|
|
||||||
这里还有一些其它的学习资源噢~
|
我们通过 `return `关键字返回一组值。事实上,任何一个有返回值(单个或多个)的函数都必须以 `return `或 `panic`(参考[第 13 章](13.0.md))结尾。
|
||||||
|
|
||||||
- [《Go编程基础》](https://github.com/Unknwon/go-fundamental-programming)
|
|
||||||
- [《Go Web编程》](https://github.com/astaxie/build-web-application-with-golang)
|
|
||||||
- [《Go名库讲解》](https://github.com/Unknwon/go-rock-libraries-showcases)
|
|
||||||
|
|
||||||
神马?你说你不想学习?那好吧,去逛逛看看行情也行~
|
|
||||||
|
|
||||||
- [Go Walker](https://gowalker.org) **Go 项目 API 文档在线浏览工具**
|
|
||||||
- [Go 中国社区](http://bbs.go-china.org)
|
|
||||||
- [Go语言学习园地](http://studygolang.com/)
|
|
||||||
- [Golang中国](http://golangtc.com)
|
|
||||||
|
|
||||||
#6.2 函数参数与返回值
|
|
||||||
函数能够接收参数供自己使用,也可以返回零个或多个值(我们通常把返回多个值称为返回一组值)。相比与C、C++、Java和C#,多值返回是Go的一大特性,为我们判断一个函数是否正常执行(参考[5.2节](05.2.md))提供了方便。
|
|
||||||
|
|
||||||
我们通过`return`关键字返回一组值。事实上,任何一个有返回值(单个或多个)的函数都必须以`return`或`panic`(参考[第13章](13.0.md))结尾。
|
|
||||||
|
|
||||||
在函数块里面,`return`之后的语句都不会执行。如果一个函数需要返回值,那么这个函数里面的每一个代码分支(code-path)都要有`return`语句。
|
在函数块里面,`return`之后的语句都不会执行。如果一个函数需要返回值,那么这个函数里面的每一个代码分支(code-path)都要有`return`语句。
|
||||||
|
|
||||||
@@ -36,12 +20,13 @@
|
|||||||
|
|
||||||
函数定义时,它的形参一般是有名字的,不过我们也可以定义没有形参名的函数,只有相应的形参类型,就像这样:`func f(int, int, float64)`
|
函数定义时,它的形参一般是有名字的,不过我们也可以定义没有形参名的函数,只有相应的形参类型,就像这样:`func f(int, int, float64)`
|
||||||
|
|
||||||
没有参数的函数通常被称为*niladic*函数(niladic function),就像`main.main()`。
|
没有参数的函数通常被称为 *niladic* 函数(niladic function),就像 `main.main()`。
|
||||||
|
|
||||||
##6.2.1 按值传递(call by value) 按引用传递(call by reference)
|
# #6.2.1 按值传递(call by value) 按引用传递(call by reference)
|
||||||
Go默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过程中可能对副本的值进行更改,但不会影响到原来的变量,比如`Function(arg1)`。
|
|
||||||
|
|
||||||
如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号,比如&variable)传递给函数,这就是按引用传递,比如`Function(&arg1)`,此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针的值所指向的地址上的值不会被复制;我们可以通过这个指针的值来修改这个值所指向的地址上的值。(**译者注:指针也是变量类型,有自己的地址和值,通常指针的值指向一个变量的地址。所以,按引用传递也是按值传递。**)
|
Go默认使用按值传递来传递参数,也就是传递参数的副本。函数接收参数副本之后,在使用变量的过程中可能对副本的值进行更改,但不会影响到原来的变量,比如 `Function(arg1)`。
|
||||||
|
|
||||||
|
如果你希望函数可以直接修改参数的值,而不是对参数的副本进行操作,你需要将参数的地址(变量名前面添加&符号,比如&variable)传递给函数,这就是按引用传递,比如 `Function(&arg1)`,此时传递给函数的是一个指针。如果传递给函数的是一个指针,指针的值(一个地址)会被复制,但指针的值所指向的地址上的值不会被复制;我们可以通过这个指针的值来修改这个值所指向的地址上的值。(** 译者注:指针也是变量类型,有自己的地址和值,通常指针的值指向一个变量的地址。所以,按引用传递也是按值传递。 **)
|
||||||
|
|
||||||
几乎在任何情况下,传递指针(一个32位或者64位的值)的消耗都比传递副本来得少。
|
几乎在任何情况下,传递指针(一个32位或者64位的值)的消耗都比传递副本来得少。
|
||||||
|
|
||||||
@@ -51,7 +36,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
|||||||
|
|
||||||
但是绝大部分的函数还是带有返回值的。
|
但是绝大部分的函数还是带有返回值的。
|
||||||
|
|
||||||
如下,simple_function.go里的`MultiPly3Nums`函数带有三个形参,分别是`a`、`b`、`c`,还有一个`int`类型的返回值(被注释的代码具有和未注释部分同样的功能,只是多引入了一个本地变量):
|
如下,simple_function.go里的 `MultiPly3Nums` 函数带有三个形参,分别是 `a`、`b`、`c`,还有一个 `int` 类型的返回值(被注释的代码具有和未注释部分同样的功能,只是多引入了一个本地变量):
|
||||||
|
|
||||||
示例 6.2 [simple_function.go](examples/chapter_6/simple_function.go)
|
示例 6.2 [simple_function.go](examples/chapter_6/simple_function.go)
|
||||||
|
|
||||||
@@ -89,12 +74,13 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
|||||||
b = &a
|
b = &a
|
||||||
}
|
}
|
||||||
|
|
||||||
##6.2.2 命名的返回值(named return variables)
|
## 6.2.2 命名的返回值(named return variables)
|
||||||
|
|
||||||
如下,multiple_return.go里的函数带有一个`int`参数,返回两个`int`值;其中一个函数的返回值在函数调用时就已经被赋予了一个初始零值(the return values are filled in at the calling function in a parallel assignment)。
|
如下,multiple_return.go里的函数带有一个`int`参数,返回两个`int`值;其中一个函数的返回值在函数调用时就已经被赋予了一个初始零值(the return values are filled in at the calling function in a parallel assignment)。
|
||||||
|
|
||||||
`getX2AandX3`与`getX2AndX3_2`两个函数演示了如何使用非命名返回值与命名返回值的特性。当需要返回多个非命名返回值时,需要使用`()`把它们括起来,比如`(int, int)`。
|
`getX2AandX3` 与 `getX2AndX3_2 `两个函数演示了如何使用非命名返回值与命名返回值的特性。当需要返回多个非命名返回值时,需要使用 `()` 把它们括起来,比如 `(int, int)`。
|
||||||
|
|
||||||
命名返回值作为结果形参(result parameters)被初始化为相应类型的零值,当需要返回的时候,我们只需要一条简单的不带参数的return语句。需要注意的是,即使只有一个命名返回值,也需要使用`()`括起来(参考[6.6节](06.6.md)的fibonacci.go函数)。
|
命名返回值作为结果形参(result parameters)被初始化为相应类型的零值,当需要返回的时候,我们只需要一条简单的不带参数的return语句。需要注意的是,即使只有一个命名返回值,也需要使用`()`括起来(参考[第 6. 6节](06.6.md)的fibonacci.go函数)。
|
||||||
|
|
||||||
示例 6.3 [multiple_return.go](examples/chapter_6/multiple_return.go)
|
示例 6.3 [multiple_return.go](examples/chapter_6/multiple_return.go)
|
||||||
|
|
||||||
@@ -152,10 +138,11 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
|||||||
|
|
||||||
编写一个名字为MySqrt的函数,计算一个float64类型浮点数的平方根,如果参数是一个负数的话将返回一个错误。编写两个版本,一个是非命名返回值,一个是命名返回值。
|
编写一个名字为MySqrt的函数,计算一个float64类型浮点数的平方根,如果参数是一个负数的话将返回一个错误。编写两个版本,一个是非命名返回值,一个是命名返回值。
|
||||||
|
|
||||||
##6.2.3 空白符(blank identifier)
|
## 6.2.3 空白符(blank identifier)
|
||||||
|
|
||||||
空白符用来匹配一些不需要的值,然后丢弃掉,下面的blank_identifier.go就是很好的例子。
|
空白符用来匹配一些不需要的值,然后丢弃掉,下面的blank_identifier.go就是很好的例子。
|
||||||
|
|
||||||
`ThreeValues`是拥有三个返回值的不需要任何参数的函数,在下面的例子中,我们将第一个与第三个返回值赋给了`i1`与`f1`。第二个返回值赋给了空白符`_`,然后自动丢弃掉。
|
`ThreeValues `是拥有三个返回值的不需要任何参数的函数,在下面的例子中,我们将第一个与第三个返回值赋给了 `i1` 与 `f1`。第二个返回值赋给了空白符 `_`,然后自动丢弃掉。
|
||||||
|
|
||||||
示例 6.4 [blank_identifier.go](examples/chapter_6/blank_identifier.go)
|
示例 6.4 [blank_identifier.go](examples/chapter_6/blank_identifier.go)
|
||||||
|
|
||||||
@@ -207,7 +194,8 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
|||||||
|
|
||||||
Minimum is: 65, Maximum is 78
|
Minimum is: 65, Maximum is 78
|
||||||
|
|
||||||
##6.2.4 改变外部变量(outside variable)
|
## 6.2.4 改变外部变量(outside variable)
|
||||||
|
|
||||||
传递指针给函数不但可以节省内存(因为没有复制变量的值),而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用`return`返回。如下的例子,`reply`是一个指向`int`变量的指针,通过这个指针,我们在函数内修改了这个`int`变量的数值。
|
传递指针给函数不但可以节省内存(因为没有复制变量的值),而且赋予了函数直接修改外部变量的能力,所以被修改的变量不再需要使用`return`返回。如下的例子,`reply`是一个指向`int`变量的指针,通过这个指针,我们在函数内修改了这个`int`变量的数值。
|
||||||
|
|
||||||
示例 6.6 [side_effect.go](examples/chapter_6/side_effect.go)
|
示例 6.6 [side_effect.go](examples/chapter_6/side_effect.go)
|
||||||
@@ -232,7 +220,8 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
|||||||
|
|
||||||
这仅仅是个指导性的例子,当需要在函数内改变一个占用内存比较大的变量时,性能优势就更加明显了。然而,如果不小心使用的话,传递一个指针很容易引发一些不确定的事,所以,我们要十分小心那些可以改变外部变量的函数,在必要时,需要添加注释以便其他人能够更加清楚的知道函数里面到底发生了什么。
|
这仅仅是个指导性的例子,当需要在函数内改变一个占用内存比较大的变量时,性能优势就更加明显了。然而,如果不小心使用的话,传递一个指针很容易引发一些不确定的事,所以,我们要十分小心那些可以改变外部变量的函数,在必要时,需要添加注释以便其他人能够更加清楚的知道函数里面到底发生了什么。
|
||||||
|
|
||||||
##链接
|
## 链接
|
||||||
|
|
||||||
- [目录](directory.md)
|
- [目录](directory.md)
|
||||||
- 上一节:[函数介绍](06.1.md)
|
- 上一节:[函数介绍](06.1.md)
|
||||||
- 下一节:[传递不定参数](06.3.md)
|
- 下一节:[传递变长参数](06.3.md)
|
||||||
|
19
eBook/06.3.md
Normal file
19
eBook/06.3.md
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
## 啊哦,亲,你看得也太快了。。。还没翻译完呢 0 0
|
||||||
|
|
||||||
|
要不等到 **2014 年 7 月 12 日** 再来看看吧~~
|
||||||
|
|
||||||
|
这里还有一些其它的学习资源噢~
|
||||||
|
|
||||||
|
- [《Go编程基础》](https://github.com/Unknwon/go-fundamental-programming)
|
||||||
|
- [《Go Web编程》](https://github.com/astaxie/build-web-application-with-golang)
|
||||||
|
- [《Go名库讲解》](https://github.com/Unknwon/go-rock-libraries-showcases)
|
||||||
|
|
||||||
|
神马?你说你不想学习?那好吧,去逛逛看看行情也行~
|
||||||
|
|
||||||
|
- [Go Walker](https://gowalker.org) **Go 项目 API 文档在线浏览工具**
|
||||||
|
- [Go 中国社区](http://bbs.go-china.org)
|
||||||
|
- [Go语言学习园地](http://studygolang.com/)
|
||||||
|
- [Golang中国](http://golangtc.com)
|
||||||
|
|
||||||
|
# 6.3 传递变长参数
|
||||||
|
|
@@ -48,6 +48,7 @@
|
|||||||
- 第6章:[函数(function)](06.0.md)
|
- 第6章:[函数(function)](06.0.md)
|
||||||
- 6.1 [介绍](06.1.md)
|
- 6.1 [介绍](06.1.md)
|
||||||
- 6.2 [参数与返回值](06.2.md)
|
- 6.2 [参数与返回值](06.2.md)
|
||||||
|
- 6.3 [传递变长参数](06.3.md)
|
||||||
- 第7章:数组(array)与切片(slice)
|
- 第7章:数组(array)与切片(slice)
|
||||||
- 第8章:Maps
|
- 第8章:Maps
|
||||||
- 第9章:包(package)
|
- 第9章:包(package)
|
||||||
|
Reference in New Issue
Block a user