Golang tips ----- 函数

1、在函数调用时,Golang没有默认参数值

2、一个函数声明如果没有函数体,表面该函数不是由Golang实现的,这样的声明定义了函数标识符

3、拥有函数名的函数只能在包级语法块中被声明

4、函数值(闭包)属于引用类型并且不可比较

5、在循环中生成的所有函数值共享相同的循环变量,并且需要注意的是,函数值记录的是循环变量的地址,而不是循环变量某一刻的值。如果函数值都在循环结束运行的话,那对于循环变量,每个函数对应的都是相同的值。如下面的代码所示,最后迭代运行函数切片,输出的都将是相同的值5。因为它们记录的是变量n的地址,而n最后的值为5。

package main

import "fmt"

func main() {
        var f []func()
        nums := []int{1, 2, 3, 4, 5}
        for _, n := range nums {
                f = append(f, func(){
                        fmt.Println(n)
                })
        }

        for _, fn := range f {
                fn()
        }
}

  

解决方法很简单,每次循环将循环变量赋值给一个临时变量t,并且在函数值中使用t。那么每个函数值都有n在各自时刻对应的副本t,而不会共享循环变量n。代码如下:

package main

import "fmt"

func main() {
        var f []func()
        nums := []int{1, 2, 3, 4, 5}
        for _, n := range nums {
                t := n
                f = append(f, func(){
                        fmt.Println(t)
                })
        }

        for _, fn := range f {
                fn()
        }
}

   对于在循环中使用go语句或者defer语句,遇到此类问题解决的方法也是类似的。

6、在一个函数中执行多条defer语句,它们的执行顺序和声明顺序相反

7、当panic发生时,程序会中断运行,并立即执行在该goroutine中被延迟的函数(defer 函数)

时间: 2024-10-04 13:23:47

Golang tips ----- 函数的相关文章

golang的函数

在golang中, 函数是第一类值(first-class object), 即函数可以赋值与被赋值. 换言之, 函数也可以作为ReceiverType, 定义自己的method. 实例: http.HandleFunc(pattern string, handler func(ResponseWriter, *Request)) 就是使用上述思想实现. type HandlerFunc func(ResponseWriter, *Request) func (f HandlerFunc) Se

Golang理解-函数变量

函数变量 函数作为变量值 函数变量是把函数作为值保存到变量中. 在Golang中,,函数也是一种类型,可以和其他类型一样被保存在变量中.例如: package main // 将函数作为值保存到变量中 import ( "fmt" ) func fire() { fmt.Println("fire") } func main(){ f := fire() // 将变量f声明为func()类型,此时f就被俗称为"回调函数", 此时f的值为nil f

golang(06)函数介绍

原文链接 http://www.limerence2017.com/2019/09/11/golang11/#more 函数简介 函数是编程语言中不可缺少的部分,在golang这门语言中函数是一等公民.也是使用好golang的必备技能.看下golang函数的格式 123 func 函数名(函数参数)返回值类型{ } 一个简单的函数 123 func HelloFunc(str string) string{ return str} 该函数返回传入的字符串,函数调用如下 1 fmt.Println

Golang泛型函数

目前,golang还不支持模板函数(类型参数化),所以看上去不得不为每一种类型都实现一个函数.但是Golang可以利用空接口interface{}和闭包/高阶函数来实现泛型函数. 1 空接口 空接口interface{}是指方法集为空的接口,任何类型的值都可以赋值给空接口.接口相关内容请参见另一篇博客<Golang中的接口> // interface{} func minimum(first interface{}, rest ...interface{}) interface{} {    

[golang note] 函数定义

普通函数定义 √ golang函数基本组成:关键字func.函数名.参数列表.返回值.函数体和返回语句. • 语法如下 func 函数名(参数列表) (返回值列表) { // 函数体 } • 示例如下 package main import "fmt" import "errors" func Add(a int, b int) (ret int, err error) { if a < 0 || b < 0 { // 假定只支持两个非负数字的加法 er

golang 原子操作函数

golang中的原子操作在sync/atomic package中. 下文以比较和交换操作函数为例,介绍其使用. CompareAndSwapInt32 比较和交换操作是原子性的. // CompareAndSwapInt32 executes the compare-and-swap operation for an int32 value. func CompareAndSwapInt32(addr *int32, old, new int32) (swapped bool) 判断参数add

golang中函数类型

今天看Martini文档,其功能列表提到完全兼容http.HandlerFunc接口,就去查阅了Go: net/http的文档,看到type HandlerFunc这部分,顿时蒙圈了.由于之前学习的时候没有关注过function types的知识点,就Google了一些文章,才算是有了个大概的了解. 从golang的官方文档得知function types的解释是这样的. A function type denotes the set of all functions with the same

[Go] golang原子函数实现goroutine同步

启动了两个goroutine,并完成一些工作.在各自循环的每次迭代之后,在goroutine 会使用LoadInt64 来检查shutdown 变量的值.这个函数会安全地返回shutdown 变量的一个副本.如果这个副本的值为1,goroutine 就会跳出循环并终止. package main import ( "fmt" "sync" "sync/atomic" "time" ) var ( //通知正在执行的gorout

Golang中函数结构体,将函数转换为接口

函数结构体,将函数转换为接口 定义一个函数类型 F,并且实现接口 A 的方法,然后在这个方法中调用自己.这是 Go 语言中将其他函数转换为接口 A 的常用技巧(参数返回值定义与 F 一致) 实现一个动态生成的"回调函数",比如缓存中,当key不存在,则需要从数据库或文件等远程数据源中取数据.所以回调函数不能写死. 采用用户自定义回调函数的方法,因此,在缓存的数据结构中,有一个成员方法变量为回调函数. 下面这段代码就是一个示例. type Getter interface { Get(k