Go语言核心之美 4.1-函数声明

erlib · · 583 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

函数有以下几个优点:可以把一系列语句打包成一个程序单元;可以把大的工作分解为小的任务,这些任务可以让不同程序员在不同时间、不同地点独立完成;一个函数可以对用户隐藏实现细节。这些优点,让函数变成了程序不可或缺的最重要的部分之一。

在此章之前,我们已经见过很多函数了,现在是时候彻底讨论函数的特性了。本章用的例子是一个网络爬虫,也是web搜索引擎中负责抓取网页的组件,他们会根据抓取到的网页中的链接继续去抓取该链接指向的页面,这个例子可以让我们学习递归函数、匿名函数、错误处理及函数的很多其它特性。

函数声明包含了函数名,可省略的参数列表、返回值列表以及函数体:

func name(parameter-list) (result-list) {
    body
}

参数列表描述了参数名和参数类型,这些参数是函数范围的局部变量,值由调用者传入。返回值列表描述了函数返回值的名字和类型,如果函数只返回一个不具名变量或者干脆没有返回值,那返回值列表的括号是可以省略的。如果一个函数声明不包含返回值列表,那么函数体执行完毕后,不会返回任何值:

func hypot(x, y float64) float64 {
    return math.Sqrt(x*x + y*y)
}
fmt.Println(hypot(3,4)) // "5"

x和y是参数名,3和4是调用时传入的参数值,函数返回了一个float64类型的值。

返回值也可以像参数一样被命名,在这种情况下,返回值被声明成函数范围的局部变量,并会初始化为对应类型的零值。

如果函数在声明时有返回值列表,那该函数必须要执行到return语句,除非函数无法执行到结尾处:例如发生了panic或者存在没有break的无限循环。

正如hypot函数一样,如果多个参数或者返回值有相同的类型,我们可以一起集中声明,下面两个声明是等价的:

func f(i, j, k int, s, t string)                 { /* ... */ }
func f(i int, j int, k int,  s string, t string) { /* ... */ }

下面的4个函数,每个函数都有2个int参数和一个int返回值,但是我们用4种不同的方法进行了声明。这里要注意下划线(空白操作符)的使用:

func add(x int, y int) int   {return x + y}
func sub(x, y int) (z int)   { z = x - y; return}
func first(x int, _ int) int { return x }
func zero(int, int) int      { return 0 }

fmt.Printf("%T\n", add)   // "func(int, int) int"
fmt.Printf("%T\n", sub)   // "func(int, int) int"
fmt.Printf("%T\n", first) // "func(int, int) int"
fmt.Printf("%T\n", zero)  // "func(int, int) int"

函数类型就是函数签名,如果两个函数的参数列表和返回值列表的变量类型能一一对应,那么这两个函数就有相同的签名。参数和返回值的变量名以及是否集中声明并不会影响函数签名。

函数调用的传参必须按照参数声明的顺序。Go语言是没有默认参数值的说法,也没有任何方法通过参数名指定传入参数的值,因此除了文档外,参数和返回值的变量名对于函数调用者是没有任何意义的。

在函数体中,参数是局部变量,被初始化为调用者传的值。函数的参数和具名返回值是函数最外层的局部变量,它们的词法块就是整个函数。

参数是通过值来传递的,因此传递过去的都是原来变量的拷贝,对参数的修改不会影响到原来的变量。但是,如果参数是引用类型,例如指针、slice、map、function、channel等,那对参数的修改可能会影响原来的变量。

你可能会在标准库中看到没有函数体的函数声明,这表示该函数不是用Go实现的:

package math

func Sin(x float64) float //该函数用汇编实现


有疑问加站长微信联系(非本文作者)

本文来自:CSDN博客

感谢作者:erlib

查看原文:Go语言核心之美 4.1-函数声明

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

583 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传