Go语言之方法

一. 方法

1.1 概述

带有接受者的函数,我们称为方法。本质上一个方法就是一个特殊类型关联的函数。go语言中就可以给任意自定义类型(包括内置类型,但是不包括指针类型)添加对应的方法
方法的语法:

    func(receiver ReceiverType)funcName(parms)(results)
    
  • 方法总是绑定对象实例,并隐式将实例作为第一实参
  • 参数receiver可以任意命名,如果在方法中没有使用,也是可以省略的
  • 参数ReceiverType的类型可以是T或者是T*。 基类型T不能使接口或者指针
  • 不支持重载方法,也就是说不能定义名字相同但是参数不同的方法
  • 只要接受者类型不同,就算方法名字一样也是不同的方法,不会出现重复定义函数的错误

1.2 给类型添加方法

1.2.1 给基础类型添加方法
type long int
func (tmp long)Add02(other long) long {
    return tmp + other
}
func main() {
    var a long = 2
    result := a.Add02(3)
    fmt.Println(result)
}
1.2.2 给结构体类型添加方法
package main

import "fmt"

type Person struct {
    name string
    sex byte
    age int
}

//带有接收者的函数叫做方法
func (p Person)PrintInfo()  {
    fmt.Println("p = " , p)
}

//通过一个函数,给成员赋值
func (p *Person)SetInfo(m string,s byte ,a int)  {
    p.name = m
    p.age = a
    p.sex = s
}


func main() {
    p := Person{"mick" , 'm', 12 }
    p.PrintInfo()


    var p1 Person
    p1.SetInfo("mick1" , 'f' , 13)
    p1.PrintInfo()
}

1.3 值语义和引用语义

package main

import "fmt"

type Person struct {
    name string
    sex byte
    age int
}


//修改成员变量的值
//参数就是普通变量,不是指针,值语义 不能修改 会拷贝一份
func (p Person)SetInfoValue(m string,s byte ,a int)  {
    p.name = m
    p.age = a
    p.sex = s
    fmt.Printf("SetinfoValue == %p \n" , &p)
}

//参数就是指针,引用语义 , 可以修改
func (p  *Person)SetInfoPoint(m string,s byte ,a int)  {
    p.name = m
    p.age = a
    p.sex = s
    fmt.Printf("SetInfoPoint == %p \n" , &p)

}


func main() {

    var p1 Person
    fmt.Printf("&p1 == %p \n" , &p1)  //打印地址

    p1.SetInfoValue("mike", 'm' , 17)  //打印内容  修改失败
    fmt.Println("p1 = ", p1)
    
    /*
        &p1 == 0xc420098020 
        SetinfoValue == 0xc420098040   //地址不一样,说明函数里拷贝的一份,修改的是拷贝的 不是原来的p1,显示也是没有修改成功的
        p1 =  { 0 0}
    */
    


    p1.SetInfoPoint("ricky", 'f' , 20)  //打印内容 修改成功
    fmt.Println("p1 = ", p1)
    
    /*
        &p1 == 0xc420098020 
        SetInfoPoint == 0xc42008e020  //地址一样,说明函数里修改的就是原来的P1,结果也显示修改成功了
        p1 =  {ricky 102 20}
    */
    
}

1.4 方法集

类型的方法集是指能被该类型的值调用的所有的方法的集合
用实例value和指针point调用方法不受方法集的约束,编译器编译总是查找全部的方法,并且自动转化receier实参

1.5 方法的继承

package main

import "fmt"

type Person struct {
    name string
    sex byte
    age int
}


func (p  *Person)PrintInfo(){
    fmt.Printf("name =  %s , age = %d , sex = %c" , p.name,p.age,p.sex)
}


//Studet继承了Person的成员字段,就继承了成员和方法
type Student struct {
    Person
    id int
    addr string
}

//Student也实现了一个方法和Person的方法同名,这就是方法的重写
func (s  *Student)PrintInfo(){
    fmt.Printf("name =  %s , age = %d , sex = %c , addr = %s" , s.name,s.age,s.sex , s.addr)
}


func main() {

    s := Student{Person{"ricky" , 'm' , 18} , 2 , "nj"}
    /*
    
    */
    s.PrintInfo()
}

你可能感兴趣的:(Go语言之方法)