微信号:fed-talk

介绍:公众号开通于2016年,内容起于前端而不止于前端.

Go 函数也是一等公民

2018-04-11 14:47 icepy

和JavaScript一样,在Go语言的世界里,函数也是一等公民,一个函数几乎就是一个代码块,不过和JavaScript不一样的是,Go的函数没有很明确的顺序,也就是说,你编写的函数在顺序上是无关紧要的,不过还是最好放在main函数之后。假设,你有一组文件,如下:


/bin

/pkg

/src

/src/main.go

/src/cell/xx.go


每一个文件里都可以有init函数,但是整个程序的结构上,只能有一个main函数。编译器在编译阶段,会把这些文件全部link在一起,但每一个init函数的调用顺序是从最里面外最外面开始调用的。比如main.go和cell/xx.go文件中都有init函数,那么init函数的调用会从cell/xx.go开始,一直到main.go文件中的init函数,最后才是main函数。(init函数可以不写,但main函数必须写)


有一点上,对于函数的{},Go有一定的规则:


func c()
{
    // 这是不合法的
}


func c(){
    // 这是合法的
}


在JS里就没有这样的规矩,{} 怎么写都是合法的。


既然大家都是函数,在某些形式上都比较类似,一样可以传参数,返回参数,值传递还是引用传递,表达式,还是闭包。有趣的是,在JS中,基础类型都是值传递,只有对象才是引用传递。在Go语言中,如果你不是传递指针,所有的一切都是值传递,也就是说它会copy一份副本。这一点上,我觉得会比JS更有用,因为我能很精准的去控制,想要值传递还是引用传递,不过在性能上,大块的还是传递指针的比较好,指针引用着内存地址,这是一个比较方便的方式。


对于返回值,也是有一定的区别,JS只能有一个返回值,但是Go可以使用命名返回,这也就是意味着,可以返回多个值。(和Python里的元组特别像)


对于闭包,两者的处理方式都是一样的,同时引用着外部函数的scope,于是你可以访问外部函数scope内的所有变量,也可以将外部函数内的变量,hold在闭包函数中,这里的一个特性,在内存释放时特别要注意,由于你把外部函数内的变量hold在了闭包函数中,由于引用未断开,GC是不会去回收的,如果这种特性被滥用,对于程序的性能来说,是会受到非常大的影响。这就是为什么defer关键字作用会那么大,你可以在defer中去释放这些。


定义一个简单的函数:



package main

import "fmt"

func main(){  
   c() }
func c(){  fmt.Println("1234") }


将函数当参数传递:


package main

import "fmt"

func main(){  
   c(12,a) }
func c(num int, f, func(int)){  
   f(num) }
func a(num int){   fmt.Println(num) }


给函数赋值:


package main

import "fmt"

func main(){  
 c := func(){     fmt.Println("1234")  }  
 c() }


函数这个事情,有很多有趣的特性可以挖掘,大家如果有兴趣,不妨来挖掘一下。




长按二维码关注公众号:

你也可以关注我的新浪微博,搜索i_icepy,很期待和大家交流

 
象尘说 更多文章 Go Echo Web Framework Go struct interface 离开,是为了将生活过成自己想要的样子 Go,从现在开始 Android远程调试Web页面
猜您喜欢 Message Queue的设计和实现(3) 使用 React Native 重写大型 Ionic 应用后,我们想分享一下这 「我们本来就是一群很酷的人,为何不一起来做一些很酷的事情呢?」 CCBN2017,观止云与您相约! Linux 内存寻址之分页机制