function是一片代码块的集合,可以向其中传递参数,返回结果。而参数和结果的类型和个数定义了这片代码块的样子,也叫做签名。在Go中,function可以是没有名字的,也叫作匿名函数或闭包。下面看一个函数的例子:
package main
import (
"fmt"
)
// 有名函数
func named_function(oldName string) (newName string) {
return oldName + "-named"
}
func main() {
fmt.Println(named_function("jack"))
// 匿名函数
anonymousFunc := func(oldName string) (newName string) {
return oldName + "-anonymous"
}
fmt.Println(anonymousFunc("jack"))
}
匿名函数可以不赋值给变量,而是直接使用func(){}()的形式进行调用。Go的函数作为一级公民,像int,bool等其他基础类型一样,可以作为变量传递和使用。一般的编程语言都有类似于函数指针的类型,函数指针也可以像变量一样使用。不知为什么Go要特别强调?
method也不是什么新概念。method更多像是有限制的function,将对象与function关联起来。在面向对象里叫做方法,和其他面向对象语言的使用方法并没有区别。method可以修改对象里的数据成员,使对象的状态发生改变;也可以将数据成员以某种方式向外暴露。下面看一个例子:
package main
import (
"fmt"
)
type num struct {
a int
}
func (n *num) set(a int) {
n.a = a
}
func (n num) setAndShow(a int) {
n.a = a
fmt.Println(n.a)
}
func main() {
n := num{a: 0}
n.setAndShow(1)
fmt.Println(n.a) // 0
n.set(2)
fmt.Println(n.a) // 2
}
上面为变量num的定义了两个method:set和setAndShow。从运行的结果发现setAndShow方法,并没有改变变量n数据成员a的值。这是为什么呢?因为sheAndShow方法接收的参数是num类型,而不是*num类型。说到这里就要先区分非指针和指针类型。
非指针类型就是不带*的类型。而指针类型则带*。指针类型用于保存变量的地址,通过解引用的方式,可以修改变量的内容,从而达到非指针类型修改变量值的效果。
Go的函数和方法都是以值的方式传递参数,就是传递参数的一个副本。如果变量是指针类型,则传递指针的副本,如set函数的参数;如果变量是非指针类型,则传递变量的副本。在setAndShow函数中就是将变量n的副本传递进方法中,所以参数就以变量n没有关联了,修改参数的成员并不会反映到变量n上。
一般不需要修改数据成员,并且占用内存小的类型,会向函数或方法中传递非指针对象,而不是指针对象。因为传递参数的方式,成本很低,也能达到效果。