Go 函数也是一等公民

和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有一定的规则:

funcc(){ // 这是不合法的}

funcc(){ // 这是合法的}

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

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

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

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

定义一个简单的函数:

packagemain

import"fmt"

funcmain(){

c()}

funcc(){ fmt.Println("1234")}

将函数当参数传递:

packagemain

import"fmt"

funcmain(){

c(12,a)}

funcc(numint, f,func(int)){

f(num)}

funca(numint){ fmt.Println(num)}

给函数赋值:

packagemain

import"fmt"

funcmain(){

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

c()}

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

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

  • 发表于:
  • 原文链接http://kuaibao.qq.com/s/20180411G0WC5X00?refer=cp_1026
  • 腾讯「腾讯云开发者社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 cloudcommunity@tencent.com 删除。

扫码关注腾讯云开发者

领取腾讯云代金券