mirror of
https://github.com/unknwon/the-way-to-go_ZH_CN.git
synced 2025-08-12 00:11:36 +08:00
06.1
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
#6.1 函数介绍
|
||||
# 6.1 介绍
|
||||
|
||||
每一个程序都包含很多的函数:函数是基本的代码块。
|
||||
|
||||
Go是编译型语言,所以函数编写的顺序是无关紧要的;鉴于可读性的需求,最好把 main() 函数写在文件的前面,其他函数按照一定逻辑顺序进行编写(例如函数被调用的顺序)。
|
||||
@@ -7,13 +8,13 @@ Go是编译型语言,所以函数编写的顺序是无关紧要的;鉴于可
|
||||
|
||||
(事实上,好的程序是非常注意DRY原则的,即不要重复你自己(Don't Repeat Yourself),意思是执行特定任务的代码只能在程序里面出现一次。)
|
||||
|
||||
当函数执行到代码块最后一行(`}`之前)或者`return`语句的时候会退出,其中`return`语句可以带有零个或多个参数;这些参数将作为返回值(参考[6.2节](06.2.md))供调用者使用。简单的`return`语句也可以用来结束for死循环,或者结束一个协程(goroutine)。
|
||||
当函数执行到代码块最后一行(`}`之前)或者`return`语句的时候会退出,其中`return`语句可以带有零个或多个参数;这些参数将作为返回值(参考[第 6.2 节](06.2.md))供调用者使用。简单的 `return `语句也可以用来结束 for 死循环,或者结束一个协程(goroutine)。
|
||||
|
||||
Go里面拥三种类型的函数:
|
||||
Go 里面拥三种类型的函数:
|
||||
|
||||
- 普通的带有名字的函数
|
||||
- 匿名函数或者lambda函数(参考[6.8节](06.8.md))
|
||||
- 方法(Methods,参考[10.6节](10.6.md))
|
||||
- 匿名函数或者lambda函数(参考[第 6.8 节](06.8.md))
|
||||
- 方法(Methods,参考[第 10.6 节](10.6.md))
|
||||
|
||||
所有类型的函数都可以有参数与返回值。函数参数、返回值以及它们的类型被统称为函数签名。
|
||||
|
||||
@@ -34,7 +35,7 @@ Go里面拥三种类型的函数:
|
||||
|
||||
pack1.Function(arg1, arg2, …, argn)
|
||||
|
||||
Function是pack1包里面的一个函数,括号里的是被调用函数的*实参*(argument):这些值被传递给被调用函数的*形参*(parameter,参考[6.2节](06.2.md))。函数被调用的时候,这些实参将被复制(简单而言)然后传递给被调用函数。函数一般是在其他函数里面被调用的,这个其他函数被称为调用函数(calling function)。函数能多次调用其他函数,这些被调用函数按顺序(简单而言)执行,理论上,函数调用其他函数的次数是无穷的(直到函数调用栈被耗尽)。
|
||||
Function是pack1包里面的一个函数,括号里的是被调用函数的*实参*(argument):这些值被传递给被调用函数的*形参*(parameter,参考[第 6.2 节](06.2.md))。函数被调用的时候,这些实参将被复制(简单而言)然后传递给被调用函数。函数一般是在其他函数里面被调用的,这个其他函数被称为调用函数(calling function)。函数能多次调用其他函数,这些被调用函数按顺序(简单而言)执行,理论上,函数调用其他函数的次数是无穷的(直到函数调用栈被耗尽)。
|
||||
|
||||
一个简单的函数调用其他函数的例子:
|
||||
|
||||
@@ -66,7 +67,7 @@ Function是pack1包里面的一个函数,括号里的是被调用函数的*实
|
||||
|
||||
funcName redeclared in this book, previous declaration at lineno
|
||||
|
||||
Go语言不支持这项特性的主要原因是函数重载需要进行多余的类型匹配影响性能;没有重载意味着只是一个简单的函数调度。所以你需要给不同的函数使用不同的名字,我们通常会根据函数的特征对函数进行命名(参考[11.12.5节](11.12.md))。
|
||||
Go语言不支持这项特性的主要原因是函数重载需要进行多余的类型匹配影响性能;没有重载意味着只是一个简单的函数调度。所以你需要给不同的函数使用不同的名字,我们通常会根据函数的特征对函数进行命名(参考[第 11.12.5 节](11.12.md))。
|
||||
|
||||
如果需要申明一个在外部定义的函数,你只需要给出函数名与函数签名,不需要给出函数体:
|
||||
|
||||
@@ -82,11 +83,12 @@ Go语言不支持这项特性的主要原因是函数重载需要进行多余的
|
||||
|
||||
这个变量知道自己指向的函数的签名,所以给它赋一个具有不同签名的函数值是不可能的。
|
||||
|
||||
函数值(functions value)之间可以相互比较:如果它们引用的是相同的函数或者都是nil的话,则认为它们是相同的函数。函数不能在其它函数里面声明(不能嵌套),不过我们可以通过使用匿名函数(参考[6.8节](06.8.md))来破除这个限制。
|
||||
函数值(functions value)之间可以相互比较:如果它们引用的是相同的函数或者都是nil的话,则认为它们是相同的函数。函数不能在其它函数里面声明(不能嵌套),不过我们可以通过使用匿名函数(参考[第 6.8 节](06.8.md))来破除这个限制。
|
||||
|
||||
目前Go没有泛型(generic)的概念,也就是说它不支持那种支持多种类型的函数。不过在大部分情况下可以通过接口(interface),特别是空接口与类型选择(type switch,参考[11.12节](11.12.md))与/或者通过使用反射(reflection,参考[6.8节](06.8.md))来实现相似的功能。使用这些技术将导致代码更为复杂、性能更为地下,所以在非常注意性能的的场合,最好是为每一个类型单独创建一个函数,而且代码可读性更强。
|
||||
目前Go没有泛型(generic)的概念,也就是说它不支持那种支持多种类型的函数。不过在大部分情况下可以通过接口(interface),特别是空接口与类型选择(type switch,参考[第 11.12 节](11.12.md))与/或者通过使用反射(reflection,参考[第 6.8 节](06.8.md))来实现相似的功能。使用这些技术将导致代码更为复杂、性能更为地下,所以在非常注意性能的的场合,最好是为每一个类型单独创建一个函数,而且代码可读性更强。
|
||||
|
||||
## 链接
|
||||
|
||||
##链接
|
||||
- [目录](directory.md)
|
||||
- 上一节:[函数](06.0.md)
|
||||
- 下一节:[函数参数与返回值](06.2.md)
|
||||
- 上一节:[函数(function)](06.0.md)
|
||||
- 下一节:[参数与返回值](06.2.md)
|
Reference in New Issue
Block a user