mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-11 19:41:43 +08:00
精校:6.2
This commit is contained in:
@@ -15,4 +15,4 @@ Golang 编程:245386165
|
||||
|
||||
|更新日期 |更新内容
|
||||
|----------|------------------
|
||||
|2015-07-19|5.6 标签与 goto
|
||||
|2015-07-20|6.2 函数参数与返回值
|
@@ -8,6 +8,7 @@
|
||||
|
||||
问题 6.1:下面的函数将不会被编译,为什么呢?大家可以试着纠正过来。
|
||||
|
||||
```go
|
||||
func (st *Stack) Pop() int {
|
||||
v := 0
|
||||
for ix := len(st) - 1; ix >= 0; ix-- {
|
||||
@@ -17,10 +18,11 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
函数定义时,它的形参一般是有名字的,不过我们也可以定义没有形参名的函数,只有相应的形参类型,就像这样:`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)
|
||||
|
||||
@@ -40,6 +42,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
示例 6.2 [simple_function.go](examples/chapter_6/simple_function.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
@@ -55,6 +58,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
// return product
|
||||
return a * b * c
|
||||
}
|
||||
```
|
||||
|
||||
输出显示:
|
||||
|
||||
@@ -76,7 +80,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
## 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` 值;其中一个函数的返回值在函数调用时就已经被赋予了一个初始零值。
|
||||
|
||||
`getX2AandX3` 与 `getX2AndX3_2` 两个函数演示了如何使用非命名返回值与命名返回值的特性。当需要返回多个非命名返回值时,需要使用 `()` 把它们括起来,比如 `(int, int)`。
|
||||
|
||||
@@ -84,6 +88,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
示例 6.3 [multiple_return.go](examples/chapter_6/multiple_return.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
@@ -112,6 +117,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
// return x2, x3
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
输出结果:
|
||||
|
||||
@@ -120,15 +126,14 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
警告:
|
||||
|
||||
return or return var 是可以的。不过,
|
||||
return var = expression(表达式) 会引发一个编译错误:
|
||||
syntax error: unexpected =, expecting semicolon or newline or }
|
||||
- return 或 return var 都是可以的。
|
||||
- 不过 `return var = expression`(表达式) 会引发一个编译错误:`syntax error: unexpected =, expecting semicolon or newline or }`。
|
||||
|
||||
即使函数使用了命名返回值,你依旧可以无视它而返回明确的值。
|
||||
|
||||
任何一个非命名返回值(使用非命名返回值是很糟的编程习惯)在 `return` 语句里面都要明确指出包含返回值的变量或是一个可计算的值(就像上面警告所指出的那样)。
|
||||
|
||||
**!!尽量使用命名返回值:会使代码更清晰、更简短,同时更加容易读懂!!**
|
||||
** 尽量使用命名返回值:会使代码更清晰、更简短,同时更加容易读懂 **
|
||||
|
||||
练习 6.1 [mult_returnval.go](exercises/chapter_6/mult_returnval.go)
|
||||
|
||||
@@ -146,6 +151,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
示例 6.4 [blank_identifier.go](examples/chapter_6/blank_identifier.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
@@ -160,6 +166,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
func ThreeValues() (int, int, float32) {
|
||||
return 5, 6, 7.5
|
||||
}
|
||||
```
|
||||
|
||||
输出结果:
|
||||
|
||||
@@ -169,6 +176,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
示例 6.5 [minmax.go](examples/chapter_6/minmax.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import "fmt"
|
||||
@@ -189,6 +197,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
}
|
||||
return
|
||||
}
|
||||
```
|
||||
|
||||
输出结果:
|
||||
|
||||
@@ -200,6 +209,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
|
||||
示例 6.6 [side_effect.go](examples/chapter_6/side_effect.go)
|
||||
|
||||
```go
|
||||
package main
|
||||
|
||||
import (
|
||||
@@ -217,6 +227,7 @@ Go默认使用按值传递来传递参数,也就是传递参数的副本。函
|
||||
Multiply(10, 5, reply)
|
||||
fmt.Println("Multiply:", *reply) // Multiply: 50
|
||||
}
|
||||
```
|
||||
|
||||
这仅仅是个指导性的例子,当需要在函数内改变一个占用内存比较大的变量时,性能优势就更加明显了。然而,如果不小心使用的话,传递一个指针很容易引发一些不确定的事,所以,我们要十分小心那些可以改变外部变量的函数,在必要时,需要添加注释以便其他人能够更加清楚的知道函数里面到底发生了什么。
|
||||
|
||||
|
Reference in New Issue
Block a user