首发于:https://studygolang.com/articles/12338
简单易懂的 Go 函数带图教程
注意:该教程仅介绍 Go 函数,不包括:可变参数、延迟函数、外部函数、方法、HTTP、封包编码等。
什么是函数?
函数是一个独立的,可以被重用的,可以一次又一次运行的代码块。函数可以有输入参数,也可以有返回值输出。
为什么我们需要函数?
增加可读性、可测试性和可维护性
使代码的不同部分可以分别执行
可以由小模块组成新的模块
可以向类型增加行为
便于组织代码
符合 DRY 原则
声明了一个函数 “Len”,输入参数为 “s”,类型为 “string”,返回值类型为 “int”。
✪ 首先:声明一个 Len 函数
✪ 然后:通过它的名字调用它
在线运行程序
输入参数和返回值类型
输入参数被用来把数据传递给函数。返回值类型被用来从函数中返回数据。从函数中返回的数据被称为“返回值”。
采用一个名为 “s” 的 string 类型“输入参数”,并返回一个“返回值类型”为 int 的没有名字的返回值。
函数签名就是一个函数的类型 -- 由输入参数类型和返回值类型组成。
Go 语言中的函数是一等公民,可以被任意赋值传递。
在线运行程序
一个函数签名的示例代码。
当一个函数被调用时,它的主体将以提供的输入参数运行。如果函数声明了至少一个返回值类型,那么函数将会返回一个或多个返回值。
你可以直接从 RuneCountInString 函数返回,因为它也返回一个 int。
这个函数使用表达式作为返回值。
函数块
每一组括号都会创建一个新的函数块,任何在函数块内声明的标识符只在该函数块内可见。
在线运行程序
现在,让我们看看输入参数和返回值类型不同风格的声明方式。
声明一个类型为 “String” 的输入参数 “s”,和一个整数返回值类型。
一个函数的输入参数和返回值类型就像变量一样起作用。
Niladic 函数
Niladic 函数不接受任何输入参数。
在线运行程序
如果一个函数没有返回值,你可以省略返回值类型和 return 这个关键字。
Singular 函数
在线运行程序
当函数只返回一个返回值时,不要使用括号。
多个输入参数和返回值
在线运行程序
多个返回值类型应该用圆括号括起来。
自动类型分配
Go 语言会自动为前面的参数声明类型。
这些声明是一样的:
错误值
一些函数通常会返回错误 -- 多个返回值让这使用很方便。
从 Write 函数直接返回和返回多个返回值类型是相同的。因为它也返回一个 int 和一个错误值。
如果一切正常,你可以直接返回 nil 作为结果:
在线运行程序
丢弃返回值
你可以使用下划线来丢弃返回值。
丢弃错误返回值(第 2 个返回值):
丢弃全部返回值:
省略参数名字
你也可以在未使用的输入参数中,把下划线当作名字使用。-- 以满足一个接口为例(或者看这里)。
命名的返回值参数让你可以像使用变量一样使用返回值,而且它让你可以使用一个空的 return。
返回值 pos 的行为就像是一个变量,函数 biggest 通过一个空的 return 返回它(return 后面没有任何表达式)。
在线运行程序
上面的程序没有经过优化,时间复杂度为 O(n)。
什么时候该使用命名返回值参数?
命名的返回值参数主要用作返回值的提示。
不要为了跳过在函数内部的变量声明而使用命名返回值参数来替代。
如果它使你的代码更具有可读性,请使用它。
当你使用命名返回值参数时,也有一个有争议的优化技巧,但编译器很快就会修复这个问题来禁止它的使用。
小心变量覆盖问题
变量 i 和 err 只在 if 代码块内可见。最后,错误不应该是 “nil”,因为 “abc” 不能被转化为整数,所以这是一个错误,但是我们没有发现这个错误。
在线运行程序
点击这里查看该问题解决方案。
值传递
函数 pass 把输入参数的值设置为了对应的零值。
我们传递两个变量给 pass 函数:
函数执行完,我们的两个变量的值没有任何变化。
这是因为,当我们传递参数给函数时,参数被自动的拷贝了一份新的变量。这被叫做值传递。
在线运行程序
值传递和指针
下面这个函数接受一个指向 string 变量的指针。它修改了指针 ps 指向的值。然后它尝试将指针的值设置为 nil。所以,指针将不会再指向传递进来的 string 变量的地址。
我们定义了一个新的变量 s,然后我们通过 & 运算符来获取它的内存地址,并将它的内存地址保存在一个新的指针变量 ps 中。
让我们把 ps 传递给 pass 函数。
在函数运行结束之后,我们会看到变量 s 的值已经改变。但是,指针 ps 仍然指向变量 s 的有效地址。
指针 ps 是按值传递给函数 pass 的,只有它指向的地址被拷贝到了函数 pass 中的一个新的指针变量(形参)。所以,在函数里面把指针变量设置为 nil 对传递给函数做参数的指针(实参)没有影响。
和 是不同的变量,但是他们都指向相同的变量 。
在线运行程序
到目前为止,我们已经学完了函数的参数声明方式。现在,让我们一起来看看如何正确的命名函数、输入参数和返回值类型。
函数命名
使用函数的好处有增加代码的可读性和可维护性等。你可能需要根据实际情况选择性的采取这些意见。
尽可能简短
当选择尽可能简短的命名。要选择简短、自描述而且有意义的名字。
使用驼峰命名法
缩略词应该全部大写:
选择描述性的参数名
使用动词
使用 is 和 are
不需要在命名中带上类型
使用 Getters 和 Setters
在 Go 语言中没有 Getters 和 Setters。但是,你可以通过函数来模拟。
Go 函数不支持的特性:
因为我会在即将发布的文章中说明下面问题的一些解决方法,所以你不需要去 duckduckgo 或者 Google 搜索答案。
函数重载 -- 它可以通过类型断言来模拟。
模式匹配器函数。
函数声明中的默认参数值。
在声明中按任意顺序通过名字指定输入参数。
希望你能把这片文章分享给你的朋友。谢谢!
via: https://blog.learngoprogramming.com/golang-funcs-params-named-result-values-types-pass-by-value-67f4374d9c0a
作者:Inanc Gumus
译者:MDGSF
校对:polaris1119
本文由 GCTT 原创编译,Go 中文网 荣誉推出
喜欢本文的朋友们,欢迎长按下图关注订阅哦!
领取专属 10元无门槛券
私享最新 技术干货