Golang 函数

121 阅读4分钟

函数

函数是基本的代码块,用于执行一个功能 Go 语言最少有一个 main ( ) 函数 可以通过函数来划分不同的功能,逻辑上每个函数执行的是指定的功能 函数声明告诉了编译器 函数的名称、参数、返回类型 Go 语言标准库提供了多种可动用的内置函数。例如,len ( ) 函数可以接受不同类型的参数并返回该参数的长度。如果传入的是字符串则返回字符串的长度,如果传入的时数组,则返回数组中包含的元素个数

Go 语言函数定义格式如下

func  func_name ( [ param list ] ) [ return_types ] {
    函数体
} 

ps :
func :函数由 func 开始声明
func_name :函数名称;函数名称 与 参数列表 一起构成了函数签名
param list :参数列表;参数就像一个占位符形式参数,当函数被调用时,可以将值传递给参数,这个值被称为实际参数;参数列表指定的是参数类型顺序参数个数;参数列表是可选的,也就是说函数可以不包含参数列表
return_types :返回类型;函数返回一列值,return_types 指定了该列值的类型;有些功能不需要返回值,也就是说返回类型是可选的
函数体 :函数定义的功能具体实现的语句代码集合
package main

import "fmt"

func main () {
    /* 返回两个数之和 */
    numSum := func (x, y int) int {
        return x + y
    }
}

/* 返回两个数的最大值 */
func max (num1, num2) int {
    if (num1 > num2) {
        return num1
    } else {
        return num2
    }
}

/* 返回两个字符串交换 */
func swap (x, y sting) (string, string) {
    return y, x
}

匿名函数

Go 语言支持 匿名函数,可作为 闭包。匿名函数是一个 内联 语句或表达式。匿名函数的优越性在于可以直接使用函数内的变量,不必声明

func getSequence () func () int {
    i := 0
    return func() int {
        i += 1
        return i
    }
}

ps :
nextNumber := getSequence()
nextNumber()   // 1
nextNumber()   // 2
nextNumber()   // 3

递归

Go 语言支持递归,递归就是在运行过程中调用自己,在使用递归时,需要设置退出条件,否则会陷入死循环

/* 阶乘 */
func Factorial (n uint64) (result uint64) {
    if (n > 1) {
        result = n * Factorial (n - 1)
        return result
    }
    return 1
}

/* 斐波那契数列 */
func fibonacci (n int) int {
    if n < 2 {
        return n
    }
    return fibonacci(n - 1) + fibonacci(n - 2)
}

方法

Go 语言中同时有函数和方法。一个方法就是包含了接受者的函数,接受者可以是命名类型或者结构体类型的一个值或者一个指针。所有给定类型的方法属于该类型的方法集

type Circle struct {
    radius  float64
}

// 该 method 属于 Circle 类型对象中的方法
func (c Circle) getArea () float64 {
    return 3.14 * c.radius * c.radius
}

ps :
Go 语言规范定义了接口方法集的调用规则:

类型 *T 的可调用方法集包含接受者为 *TT 的所有方法集
类型 T 的可调用方法集包含接受者为 T 的所有方法
类型 T 的可调用方法集不包含接受者为 *T 的方法

函数传值

Go 语言函数传值分为 值传递值、引用传递值

值传递值 是指 将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,不会影响到实际参数

/* 返回两个字符串交换 */
func swap (x, y int) (int, int) {
    var temp int

    temp = x
    x = y
    y = temp

    return temp
}

引用传值 是指 将实际参数的地址传递到函数中,那么在函数中如果对参数进行修改,将会影响到实际参数

/* 返回两个字符串交换 */
func swap (x, y *int) {
    var temp int


    temp = *x
    *x = *y
    *y = temp
}

defer关键字

Go 语言的 defer 会在当前函数或者方法返回之前执行传入的函数,它经常被用于 关闭文件描述符、关闭数据库连接 以及 解锁资源

func createPost(db *gorm.DB) error {
    tx := db.Begin()
    defer tx.Rollback()
    
    if err := tx.Create(&Post{Author: "Draveness"}).Error; err != nil {
        return err
    }
    
    return tx.Commit().Error
}

在使用数据库事务时,我们可以使用上述所示的代码,在创建事务后就立即调用 Rollback 保证事务一定会回滚;哪怕事务真的执行成功了,那么调用 tx.Commit() 之后再执行 tx.Rollback() 也不会影响已经提交的事务