Golang的学习笔记(12)--Go方法Method

目录

Go的方法Method

structMethod
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) {
   ...
}
studentStudy
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在内部帮我们自动作了转换

内嵌方法的继承

    之前在上一篇文章中提到了结构体内可以通过内嵌结构体的方式来实现类似于继承内嵌结构体字段的效果,现在我们增加了方法的使用,因此,如果内嵌结构体拥有一个方法,那么外层的结构体同样继承了内嵌结构体的方法,可以直接通过外层结构体直接访问到该方法。而如果外层结构体定义了一个同名的方法,那么外层的方法将覆盖掉内嵌方法,直接通过外层结构体访问该方法将访问到外层结构体关联的方法,而如果要使用内嵌方法,则需要一层一层嵌套访问。
    是不是感觉很熟悉?没错,这个解决方式和字段名冲突时的解决方式是相同的。