1 函数的定义

注: 小写字母开头的函数, 变量和类型只在本包内可见,大写字母开头的函数才能被其他包使用。

  1. package mymath
  2. import "errors"
  3. func Add(a int, b int) (ret int, err error) {
  4. if a < 0 || b < 0 { // 假设这个函数只支持两个非负数字的加法
  5. err= errors.New("Should be non-negative numbers!")
  6. return
  7. }
  8. return a + b, nil // 支持多重返回值
  9. }

如果参数列表中若干个相邻的参数类型的相同,比如上面例子中的 a 和 b ,则可以在参数列表中省略前面变量的类型声明

  1. func Add(a, b int)(ret int, err error) {
  2. // ...
  3. }
  4. // 如果返回值列表中多个返回值的类型相同,也可以用同样的方式合并。如果函数只有一个返回值,也可以这么写:
  5. func Add(a, b int) int {
  6. // ...
  7. }

2 函数的调用

  1. import "mymath"// 假设Add被放在一个叫mymath的包中
  2. // ...
  3. c := mymath.Add(1, 2)

3 不定参数

指函数传入的参数个数为不定数量。

  1. func myfunc(args ...int) {
  2. for _, arg := range args {
  3. fmt.Println(arg)
  4. }
  5. }

从内部实现机理上来说,类型 …type 本质上是一个数组切片,也就是 []type ,
这也是为什么上面的参数 args 可以用 for 循环来获得每个传入的参数。
假如没有 …type 这样的语法糖,开发者将不得不这么写:

  1. func myfunc2(args []int) {
  2. for _, arg := range args {
  3. fmt.Println(arg)
  4. }
  5. }

但从调用方来说,情形则完全不同:我们不得不加上 []int{} 来构造一个数组切片实例。

  1. myfunc2([]int{1, 3, 7, 13})

如果你希望传任意类型,可以指定类型为interface{}

  1. package main
  2. import "fmt"
  3. func MyPrintf(args ...interface{}) {
  4. for _, arg := range args {
  5. switch arg.(type) {
  6. case int:
  7. fmt.Println(arg, "is an int value.")
  8. case string:
  9. fmt.Println(arg, "is a string value.")
  10. case int64:
  11. fmt.Println(arg, "is an int64 value.")
  12. default:
  13. fmt.Println(arg, "is an unknown type.")
  14. }
  15. }
  16. }
  17. func main() {
  18. var v1 int = 1
  19. var v2 int64 = 234
  20. var v3 string = "hello"
  21. var v4 float32 = 1.234
  22. MyPrintf(v1, v2, v3, v4)
  23. }

4 多返回值

如果读取文件成功,则返回值中的 n 为读取的字节数, err 为 nil ,否则 err 为具体的出错信息

  1. func (file *File) Read(b []byte) (n int, err Error)

同样,从上面的方法原型可以看到,我们还可以给返回值命名,就像函数的输入参数一样。返回值被命名之后,它们的值在函数开始的时候被自动初始化为空。
在函数中执行不带任何参数的 return 语句时,会返回对应的返回值变量的值。
如果调用方调用了一个具有多返回值的方法,但是却不想关心其中的某个返回值,可以简单地用一个下划线“ _ ”来跳过这个返回值

  1. n, _ := f.Read(buf)

5 函数签名

  1. type DisposeFunc func(seq string, message []byte) (code uint32)