函数

函数声明

func 函数名字(参数列表) (返回值列表) {}

eg:

// 没有返回值
func add() {
    
}

// 单个返回值
func add(a int, b int) int {
    
}
// 或
func add(a, b int) int {
    
}

// 多个返回值
func add(a int, b int) (int, int) {
    
}

golang函数特点

  • 不支持重载,一个包不能有两个名字一样的函数

  • 函数是一等公民,函数也是一种类型,一个函数可以赋值给变量

  • 支持匿名函数,函数可以没有名字

  • 多返回值

函数可以赋值给变量

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


func main() {
    // 将函数赋值给变量
    c := add
    c(10, 20)		// 变量调用函数
}

函数也是一种类型

type add_func func(int, int) int		// 定义一个函数类型

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

// op add_func 即表示add_func的变量
func operator(op add_func, a int, b int) int {
    return op(a, b)
}

func main() {
    c := add
    sum := operator(c, 100, 200)
    fmt.Println(sum)
}

当然,也可以不用type定义,直接写

func operator(op func(int, int) int, a, b int) int {
    return op(a, b)
}

匿名函数

// 将匿名函数赋值给变量
result := func(a1, b1 int) int {
    return a1 + b1
}
result(11, 22)

// 定义时调用
result := func(a, b int) int {
    return a + b
}(11, 22)

函数参数传递方式

  • 值传递

  • 引用传递

无论是值传递,还是引用传递,传递给函数的都是变量的副本,不过,值传递是值的拷贝。引用传递是地址的拷贝,一般来说,地址拷贝更为高效。而值拷贝取决于对象的大小,对象越大,则性能越低

map、slice、chan、指针、interface默认以引用方式传递

命名返回值

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

func calc(a, b int) (sum int, avg int) {
    sum = a + b
    avg = (a + b) / 2
    return
}

可变参数

func add(arg...int) int {	// 0个或多个参数
    
}

func add(a int, arg...int) int {   // 1个或多个参数
    
}

/*
其实arg是一个slice,我们可以通过arg[index]依次访问所有参数,通过len(arg)来判断参数的个数
*/

defer

  • 当函数返回时,会执行defer语句。因此,可以用来做资源清理

  • 多个defer语句,按先进后出的方式执行

  • defer语句中的变量,在defer声明时就决定了

func a() {
    i := 0
    defer fmt.Println(i)   // 这条语句是最后执行的,而且这里的i=0,不会受下面的i=10影响
    i = 10
    return
}

func f() {
    for i := 0; i < 5; i++ {
        defer fmt.Println("%d", i)   // 根据先进后出的原则,打印4, 3, 2, 1
    }
}

defer用途

关闭文件句柄

func read() {
    file := open(filename)
    defer file.Close()
	// 文件操作
}

锁资源释放

func read() {
    mc.Lock()
    defer mc.Unlock()
    // 其他操作
}

数据库连接释放

func read() {
    conn := openDatabase()
    defer conn.Close()
    
    // 其他操作
}

defer结合匿名函数

defer func() {
    if conn != nil {
        connn.Close()
    }
}()

 

posted @ 2019-05-23 21:49  Jin同学  阅读(85)  评论(0)    收藏  举报