Go语言函数

函数的定义和调用

package main

import "fmt"

// 函数的定义
// func 函数名(参数)(返回值){
//  函数体
// }
// 函数定义
func add(a int, b int) (ret int) {
    return a + b
}

func main() {
        // 函数的调用
    result := add(1, 1)
    fmt.Println(result) //2
}
  • 函数名:由字母、数字、下划线组成。但函数名的第一个字母不能是数字。在同一个包内,函数名也不能重复。
  • 参数:参数由参数变量和参数变量类型组成,多个参数之间使用逗号分隔。
  • 返回值:返回值由返回值变量和其变量类型组成,也可以只写返回值类型,多个返回值必须使用()分隔,并用逗号分隔。
  • 函数体:实现指定功能的代码块。

参数类型简写

函数的参数中如果相邻变量的类型相同,则可以省略

func add(a , b int) int {
    return a + b
}

可变参数

可变参数是指函数的参数数量不固定。Go语言中的可变参数通过在参数名后加...来标识。需要注意的是,可变参数通常要作为函数的最后一个参数。

package main

import "fmt"

// 可变参数
func add(a ...int) (ret int) {
        // a是一个切片
    sum := 0
    for _, v := range a {
        sum += v
    }
    return sum
}

func main() {
    fmt.Println(add(1, 1))       //2
    fmt.Println(add(1, 1, 1))    //3
    fmt.Println(add(1, 1, 1, 1)) //4
}

返回值

Go语言中支持多返回值,函数如果有多个返回值必须使用()将所有返回值包裹起来。

package main

import "fmt"

// 多返回值
func add(a int, b string) (int, bool) {
    return 1, true
}

func main() {
    n, flag := add(1, "11")
    fmt.Println(n, flag)
}

返回值的命名

函数定义时,可以给函数返回值命名,并在函数体中直接使用这些变量

package main

import "fmt"

// 多返回值 返回值命名
func add(a int, b string) (num int, flag bool) {
    num = 123
    flag = false
    return
}

func main() {
    num, flag := add(1, "11")
    fmt.Println(num, flag)  //123,false
}

函数进阶

变量作用域

全局变量

全局变量是定义在函数外部的变量,它在程序整个运行周期内有效。在函数中可以访问到全局变量。

package main

import "fmt"

// 定义全局变量
var name = "jack"

func showName() {
    fmt.Println(name)
}

func main() {
    showName() // jack
}

局部变量

函数内定义的变量无法在函数外使用。

package main

import "fmt"

func showName() {
        // 只有函数内部才能使用这种定义变量的方法
    name := "jack"
    fmt.Println(name)
}

func main() {
    showName() // jack
    // 报错 不能再函数外使用函数内定义的变量
    // fmt.Println(name)
}

语句块中的局部变量

package main

import "fmt"

func showName() {
    name := "jack"
    flag := true
    if flag {
        age := 12
        fmt.Println(age)  //12
        fmt.Println(name) //jack
    }
    // 报错不能再函数外使用函数内定义的变量
    // fmt.Println(age)
    fmt.Println(name) //jack
}

func main() {
    showName() // jack
    // 报错 不能再函数外使用函数内定义的变量
    // fmt.Println(name)
}

函数类型和变量

定义函数类型

使用type关键字来定义一个函数类型。

package main

import "fmt"

// 定义函数类型
type calculation func(int, int) int

func add(x, y int) int {
    return x + y
}

func main() {
    // 定义函数类型变量
    var c calculation
    c = add
    result := c(1, 2)
    fmt.Println(result)  //3
}

函数变量类型

package main

import "fmt"

// 定义函数类型
type calculation func(int, int) int

func add(x, y int) int {
    return x + y
}

func main() {
    // 定义函数类型变量
    var c calculation
    c = add
    result := c(1, 2)
    fmt.Println(result)  //3
    fmt.Printf("%T\n",c) //main.calculation
}

高阶函数

函数作为参数

package main

import "fmt"

func add(x, y int) int {
    return x + y
}

func calc(x, y int, op func(int, int) int) int {
    return op(x, y)
}

func main() {
    fn := calc(1, 2, add)
    fmt.Println(fn) //3
}

函数作为返回值

package main

import "fmt"

func add(x, y int) int {
    return x + y
}
func sub(x, y int) int {
    return x - y
}
func do(s string) (func(int, int) int, error) {
    switch s {
    case "+":
        return add, nil
    case "-":
        return sub, nil
    default:
        return nil, nil
    }
}

func main() {
    fn, error := do("+")
    fmt.Println(fn(1, 2)) //3
    fmt.Println(error)    //<nil>
    fn2, error2 := do("-")
    fmt.Println(fn2(1, 2)) //-1
    fmt.Println(error2) // <nil>
}

匿名函数和闭包

匿名函数

在Go语言中,函数内部只能定义匿名函数

package main

import "fmt"

func main() {
    //  func(参数)(返回值){
    //     函数体
    // }
    add := func(x, y int) int {
        return x + y
    }
    fmt.Println(add(1, 1)) //2
}

闭包

闭包指的是一个函数和与其相关的引用环境组合而成的实体。

package main

import "fmt"

// 闭包
func adder() func(int) int {
    var x int
    return func(y int) int {
        x += y
        return x
    }
}

func main() {
    f := adder()
    fmt.Println(f(10))  //10
    fmt.Println(f(20))  //30
    fmt.Println(f(30))  //60
}

defer函数

Go语言中的defer语句会将其后面跟随的语句进行延时处理。在defer归属的函数即将返回时,将延迟处理的语句按defer定义的逆序进行执行。

package main

import "fmt"

func main() {
    fmt.Println("start")
    defer fmt.Println(1)
    defer fmt.Println(2)
    defer fmt.Println(3)
    fmt.Println("end")
    // start
    // end
    // 3
    // 2
    // 1
}

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 1. 概述 函数是将实现单一或者相关联功能的代码组织起来,内部实现具有封闭性的代码集合,函数可以提高应用程序的模块...
    楚江云阅读 870评论 0 1
  • 函数 Go语言函数格式func 函数名称(形参列表)(返回值列表){函数语句} Go语言函数的类型没有返回值没有形...
    喝酸奶要舔盖__阅读 406评论 0 0
  • 函数 Go语言和C语言一样也有函数的概念, Go语言中函数除了定义格式和不用声明以外,其它方面几乎和C语言一模一样...
    极客江南阅读 830评论 3 6
  • 参考博客:http://c.biancheng.net/view/52.html 关键点 希望通过下面的关键点,可...
    码二哥阅读 578评论 0 5
  • broker是消息队列的核心组建,承载了消息接收,存储和转发的职责. 因此, broker需要具备各种基本功能和高...
    _呆瓜_阅读 1,953评论 1 1