1. 函数定义和调用

函数是组织好的、可重复使用的、用来实现单一或相关联功能的代码块,其可以提高应用的模块性和代码的重复利用率。Go 语言函数与其他语言函数最大的不同是,Go 语言的函数可以支持返回任意多个值,而其他语言的函数一般只支持返回一个值。Go 语言的函数支持普通函数、匿名函数和闭包三种形式。函数的基本组成为:func关键字、函数名、参数列表、返回值、函数体和返回语句,一个Go程序至少包含一个main函数,函数是最基本的代码块。

1.1. 普通函数定义

普通函数定义语法格式:

  1. func funcName(parametername type1, parametername type2) (val returnType1, val returnType2) {
  2. //函数体
  3. return value1, value2 //返回多个值
  4. }

注:Go函数和其他语言的函数定义最明显的区别就是,可以返回多个值,所以返回值列表中需声明多个返回值类型(可以不声明返回值变量)。如果函数返回一个无名变量或者没有返回值,返回值列表可以省略。如果只有一个返回值且不声明返回值变量,返回值列表的括号可以省略。

示例:

  1. func returnTwoNumber(num1 int, num2 int) (int, int){
  2. // 原样返回传入的两个值
  3. return num1, num2
  4. }

1.2. 函数调用

函数在定义后就可被调用(无需像C语言在使用前进行前置声明),函数内的局部变量只能在函数体内使用,函数调用结束后,局部变量会被释放失效。
函数调用格式:返回值变量列表 = 函数名(实参列表)
示例:

  1. package main
  2. import "fmt"
  3. func main() {
  4. var res1 int
  5. var res2 int
  6. // 函数调用
  7. res1, res2 = returnTwoNumber(1, 2)
  8. fmt.Println(res1, res2)
  9. }
  10. func returnTwoNumber(num1 int, num2 int) (int, int) {
  11. // 原样返回传入的两个值
  12. return num1, num2
  13. }

1.3. 拓展

  1. Go语言函数借鉴了很多动态语言的优点,如:
  • 无须前置声明
  • 不支持命名嵌套定义(nested)
  • 不支持同名函数重载(overload)
  • 不支持默认参数
  • 支持不定长变参
  • 支持多返回值
  • 支持命名返回值
  • 支持匿名函数和闭包
  1. 函数属于第一类对象,具备相同签名(形参列表和返回值列表的类型相同)的两个函数被视作同一类型。

    第一类对象(first-class object)指可在运行期创建,可用作函数参数或返回值,可存入变量的实体。最常见的用法就是匿名函数。

  2. 建议函数命名规则

  • 通常是动词和介词加上名词,比如scanWords
  • 避免不必要的缩写,比如printError要比printErr更好
  • 避免使用类型关键字,比如buildUserStruct看上去会很别扭
  • 避免歧义,不能有多种用途造成误解
  • 避免只能通过大小写区分的同名函数
  • 避免与内置函数同名,会导致误用
  • 避免使用数字,除非是特定专有名词
  • 避免添加作用域提示前缀
  • 统一使用camel/pascal case拼写风格

    camel case:骆驼拼写法,依靠单词的大小写拼写复合词的做法,”骆驼拼写法”又分为两种。第一个词的首字母小写,后面每个词的首字母大写,叫做”小骆驼拼写法”(lowerCamelCase);第一个词的首字母,以及后面每个词的首字母都大写,叫做”大骆驼拼写法”(UpperCamelCase),又称”帕斯卡拼写法”(PascalCase)。

  • 使用相同术语,保持一致性

  • 使用习惯用语,比如init表示初始化,is/has返回布尔值结果
  • 使用反义词命名行为相反的函数,比如get/setmin/max

    2. 函数的参数

    2.1. 普通参数

    Golang中函数的参数,为形式参数,是局部变量,只能在函数内使用,传递方式为值传递,即传递的参数其实是实际参数的一份拷贝,而不是真正的实际参数。
    在 Go 语言中,如果相邻的形参类型相同,可以省略前几个参数的类型,只需要写最后一个参数的类型即可。

    1. // 省略前几个形参的类型,三个参数的类型都为paramType
    2. func funcName(param1, param2, param3 paramType)(returnVal returnType){
    3. return 返回值列表
    4. }

    2.2. 可变参数

    可变参数:可变参数函数是指一个函数拥有不定引数,即是它接受一个可变数目的参数。简单来说,就是函数的参数个数可变,参数类型不定的函数。

在C语言时代大家一般都用过 printf() 函数,从那个时候开始其实已经在感受可变参数的魅力和价值,如同C语言中的 printf() 函数,Go语言标准库中的 fmt.Println() 等函数的实现也依赖于语言的可变参数功能。
合适地使用可变参数,可以让代码简单易用,尤其是输入输出类函数,比如日志函数等。

3. 函数的返回值

4. 值传递和引用传递

5. 函数变量

6. 匿名函数

7. 闭包

8. defer函数