文章目录
函数
函数的格式:func+函数名+ 参数 + 返回值(可选) + 函数体
例如:
func myfunction( a, b int) (int) {
}
在Go中,函数被看作第一类值(first-class values),函数像其他值一样,拥有类型,可以被赋值给其他变量,传递给函数,从函数返回。函数类型的零值是nil。
在golang中还有两个特殊的函数,main函数和init函数。
main函数作为一个程序的入口,只能有一个。
func main() {
}
init函数在每个package是可选的,可有可无,甚至可以有多个,init函数在你导入该package时程序会自动调用init函数,所以init函数不用我们手动调用,并且它只会被调用一次,因此当一个package被多次引用时,它只会被导入一次。
func init() {
}
方法
方法能给用户自定义的类型添加新的行为。
例如:
type myInt int
func (a myInt) add(b myInt) myInt {
return a + b
}
方法和函数的区别在于方法有一个接收者,给一个函数添加一个接收者,那么它就变成了方法。接收者可以是值接收者,也可以是指针接收者。
Golang 不是一个纯粹的面向对象的编程语言,它不支持类。因此通过在一个类型上建立方法来实现与 class 相似的行为。
同名方法可以定义在不同的类型上,但是 Golang 不允许同名函数。假设有两个结构体 Square 和 Circle。在 Square 和 Circle 上定义同名的方法是合法的。
值接收者与指针接收者区别
先看下面的例子
定义一个Employee
的结构体
type Employee struct {
name string
age int
}
值接收者:
func (e Employee) changeName(newName string) {
fmt.Printf("changeName: address %p\n", &e)
e.name = newName
}
指针接收者:
func (e *Employee) changeAge(newAge int) {
fmt.Printf("changeAge: address %p\n", e)
e.age = newAge
}
main函数:
func main() {
emOne := &Employee{
name: "em1",
age: 18,
}
fmt.Printf("before emOne: %v, address: %p\n", emOne, emOne)
emOne.changeName("em1_change")
emOne.changeAge(19)
fmt.Printf("after emOne: %v, address: %p\n", emOne, emOne)
emTwo := Employee{
name: "em2",
age: 18,
}
fmt.Printf("before emTwo: %v, address: %p\n", emTwo, &emTwo)
emTwo.changeName("emTwo_change")
emTwo.changeAge(20)
fmt.Printf("after emTwo: %v, address: %p\n", emTwo, &emTwo)
}
执行结果:
before emOne: &{em1 18}, address: 0xc000004480
changeName: address 0xc0000044e0
changeAge: address 0xc000004480
after emOne: &{em1 19}, address: 0xc000004480
before emTwo: {em2 18}, address: 0xc000004520
changeName: address 0xc000004560
changeAge: address 0xc000004520
after emTwo: {em2 20}, address: 0xc000004520
通过以上结果可以看出:
对于值接收者,如果调用者也是值对象,那么会将调用者的值拷贝一份,并执行方法,方法的调用不会影响到调用者值。 如果调用者是指针对象,那么会解引用指针对象为值,然后将解引的对象拷贝一份,然后执行方法。
对于指针接收者,如果调用者是值对象,会使用值的引用来调用方法。如果调用者是指针对象,实际上也是“传值”,方法里的操作会影响到调用者,类似于指针传参,拷贝了一份指针,但是指针指向同一个对象。
使用指针作为方法的接收者的理由:
- 方法能够修改接收者指向的值。
- 避免在每次调用方法时复制该值,在值的类型为大型结构体时,这样做会更加高效。