文章15 | 阅读 7593 | 点赞0
在面向对象的语言中,类可以包括属性和方法;而在Go中,并无类的概念,往往使用结构体struct
来替代类的操作,但结构体中只有字段属性,那方法在哪里?
Go为我们提供了一种名为Method
的特殊函数,它通过作用在某个接收者上面来实现与其关联,可以实现类的方法这一需求。
invalid receiver type
func (a int) add(b int) int {return a + b}
func (a float32) add(b float32) float32 {return a+b}
Go方法定义的格式
func (recv receiver_type) methodName(parameter_list) (return_value_list) {
...
}
下面是一个方法使用的实例,我们在结构体student
上面添加上方法Study
。在方法定义的第一个括号中指定接收者变量
type student struct {
name string
id int
}
func main(){
s := student{
name : "xiao",
id : 1,
}
s.Study()
}
func (a student) Study(){
fmt.Println(a.name, "is studying")
}
上面是对结构体添加方法,我们还可以结合类型别名对其它任意类型来添加方法
type zhengxing int
func main(){
var a zhengxing
a.Print()
}
func (i zhengxing) Print(){
fmt.Println("zhengxing")
}
在上面的代码中,我们在主程序中调用方法都是先创建某个类型的变量,然后通过变量来调用方法,这种方式称之为Method Value,还有另外一种调用方法的方法,称之为Method Expression,它是通过类型来调用方法,并将类型的变量作为参数传递到方法中:
type zhengxing int
func main(){
var a zhengxing
zhengxing.Print(a)
}
func (i zhengxing) Print(){
fmt.Println("zhengxing")
}
方法中对接收者默认也是值传递,即传入方法的接收者为原始接收者的拷贝,在方法中无法直接改变真正的接收者变量。如果确实需要在方法中改变接收者,可以使用接收者的指针来传递:
type student struct {
name string
id int
}
func main(){
s := student{
name : "xiao",
id : 1,
}
s.changeId(110)
fmt.Println(s.id)
}
func (a *student) changeId(id int){
a.id = id
fmt.Println(a.id)
}
从性能方面考虑,传递一个地址比起拷贝一个类型变量更加具有优势,因此更加推荐这种传递接收者类型的指针。而且我们也可以看到在访问结构体字段时用法和非指针的结构体的用法是相同的,Go在内部帮我们自动作了转换
之前在上一篇文章中提到了结构体内可以通过内嵌结构体的方式来实现类似于继承内嵌结构体字段的效果,现在我们增加了方法的使用,因此,如果内嵌结构体拥有一个方法,那么外层的结构体同样继承了内嵌结构体的方法,可以直接通过外层结构体直接访问到该方法。而如果外层结构体定义了一个同名的方法,那么外层的方法将覆盖掉内嵌方法,直接通过外层结构体访问该方法将访问到外层结构体关联的方法,而如果要使用内嵌方法,则需要一层一层嵌套访问。
是不是感觉很熟悉?没错,这个解决方式和字段名冲突时的解决方式是相同的。
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/xah100147/article/details/106416944
内容来源于网络,如有侵权,请联系作者删除!