10.函数和方法相关的东西
函数和方法相关的东西
函数是指不属于任何结构体、类型的方法,也就是说,函数是没有接收者的;而方法是有接收者的,我们说的方法要么是属于一个结构体的,要么属于一个新定义的类型的
函数
案例
这里面add就是函数,他是独立的
func main() {
sum := add(1, 2)
fmt.Println(sum)
}
//这个函数名称是小写开头的`add`,所以它的作用域只属于所声明的包内使用,不能被其他包使用,如果我们把函数名以大写字母开头,该函数的作用域就大了,可以被其他包调用。
func add(a, b int) int {
return a + b
}
//函数名首字母大写可以被其他包调用,相当于暴露出去了
//比如Java中,就有专门的关键字来声明作用域private、protect、public等。
func Add(a, b int) int {
return a + b
}
方法
案例
//方法在定义的时候,会在func和方法名之间增加一个参数,这个参数就是接收者,这样我们定义的这个方法就和接收者绑定在了一起,称之为这个接收者的方法。
//在其他语言中可以理解为,对象方法
type person struct {
name string
}
//(p person),这个就是接收者
func (p person) String() string{
return "the person name is "+p.name
}
接收者操作
name string
}
func (receiver person) String() string {
return "操作人的名字是 "+ receiver.name
}
func main() {
p:=person{name:"董雷"}
fmt.Println(p.String())
}
//返回数据
操作人的名字是 董雷
接受者类型
值接收者
type person struct {
name string
}
func (receiver person) String() string {
return "操作人的名字是 "+ receiver.name
}
//因为是值接收者,所以modify并不为影响里面的值
func (receiver person) modify(){
receiver.name = "董华"
}
func main() {
p:=person{name:"董雷"}
p.modify() //值接收者,修改无效
fmt.Println(p.String())
}
//返回结果
操作人的名字是 董雷
指针接收者
如果我们使用一个指针作为接收者,那么就会其作用了,因为指针接收者传递的是一个指向原值指针的副本,指针的副本,指向的还是原来类型的值,所以修改时,同时也会影响原来类型变量的值。
type person struct { name string } func (receiver person) String() string { return "操作人的名字是 "+ receiver.name } //这个时候因为是指针接收者,所以会修改以前的值 func (receiver *person) modify(){ receiver.name = "董华" } func main() { p:=person{name:"董雷"} p.modify() //指针接收者,修改有效 fmt.Println(p.String()) } //返回结果 操作人的名字是 董华 //main这种方式可以 func main() { p:=person{name:"董雷"} //这样也是可以的。如果我们没有这么强制使用指针进行调用,Go的编译器自动会帮我们取指针,以满足接收者的要求。 (&p).modify() //指针接收者,修改有效 fmt.Println(p.String()) } //返回数据 操作人的名字是 董华
总之,方法的调用,既可以使用值,也可以使用指针,我们不必要严格的遵守这些,Go语言编译器会帮我们进行自动转义的,这大大方便了我们开发者。
总结
在调用方法的时候,传递的接收者本质上都是副本,只不过一个是这个值副本,一是指向这个值指针的副本。指针具有指向原有值的特性,所以修改了指针指向的值,也就修改了原有的值。我们可以简单的理解为值接收者使用的是值的副本来调用方法,而指针接收者使用实际的值来调用方法。
多值返回
就是返回多个值而已,没啥额外需要说明的
func add(a, b int) (int, error) { return a + b, nil }
可变参数
这个使用场景还是比较多的
参考案例1
参考案例2
本作品采用《CC 协议》,转载必须注明作者和本文链接
推荐文章: