• Go学习笔记-结构体中的方法


    方法是什么

    • Go方法是作用在接受者(个人理解成作用对象)上的一个函数,接受者是某种类型的变量,因此方法是一种特殊类型的函数。
    • 接收者可以是任何类型,不仅仅是结构体,Go中的基本类型(int,string,bool等)也是可以,或者说数组的别名类型,甚至可以是函数类型。但是,接受者不能是一个接口类型,因为接口是一个抽象的定义,方法是一个具体实现。
    • 一个类型加上它的方法等价于面向对象中的一个类。一个重要的区别是:在 Go 中,类型的代码和绑定在它上面的方法的代码可以不放置在一起,它们可以存在在不同的源文件,唯一的要求是:它们必须是同一个包的。
    • 类型 T(或 *T)上的所有方法的集合叫做类型 T(或 *T)的方法集。
    • 因为方法是函数,所以同样的,不允许方法重载,即对于一个类型只能有一个给定名称的方法。但是如果基于接收者类型,是有重载的:具有同样名字的方法可以在 2 个或多个不同的接收者类型上存在,比如在同一个包里这么做是允许的
    • 别名类型不能有它原始类型上已经定义过的方法(因为别名类型和原始类型底层是一样的)。

    定义方法的格式

     1 func(recv recevier_type)methodName(parameter_list)(return_value_list){} 

      方法名之前,func关键字之后的括号中指定接受者(receiver)。

      如果recv是接受者(receiver)的实例,Method1是recv的方法名,那么方法的调用遵循传统的object.name选择器符号:recv.Method1()。假如recv是一个指针,Go会自动解引用。

     1 package main
     2 
     3 import "fmt"
     4 
     5 type TwoInts struct {
     6     a int
     7     b int
     8 }
     9 func(ti *TwoInts)Add()int{
    10     return ti.a + ti.b
    11 }
    12 
    13 func(ti *TwoInts)Plus()(re int){
    14     re = ti.a * ti.b
    15     return
    16 }
    17 
    18 func(ti *TwoInts)AddOther(param int)(re int){
    19     re = ti.a + ti.b +param
    20     return
    21 }
    22 // 结构体上的例子
    23 func main(){
    24     tt := new(TwoInts)
    25     tt.a = 10
    26     tt.b = 20
    27 
    28     fmt.Println(tt.Add())
    29     fmt.Println(tt.Plus())
    30 
    31     ttt := TwoInts{3,5}
    32     fmt.Println(ttt.AddOther(7))
    33 }
    package main
    
    import "fmt"
    
    type IntVetor []int
    
    func (iv IntVetor) Sum(param int) (re int) {
        su := 0
        for _, v := range iv {
            su = su + v
        }
        re = su + param
        return
    }
    // 非结构体上的例子
    func main() {
        tv := IntVetor{3,4,5}
        fmt.Println(tv.Sum(333))
    }

      如果想给基本类型添加方法,一般是行不通的,因为基本类型和你添加方法的包不是同一个,会出现编译错误。

     方法和函数的区别

    • 方法只能被其接受者调用
    • 接收者是指针时,方法可以改变接受者的值(或状态),函数也能做到
    • 接受者和方法必须在同一个包内

    方法的接受者是值或者指针的区别

    • 当接受者是一个值的时候,这个值是该类型实例的拷贝
    • 如果想要方法改变接受者的数据,就在接受者的指针类型上定义该方法。否则,就在普通的值类型上定义方法。

     总结:指针方法和值方法都可以在指针或者非指针上被调用。也就是说,方法接收者是指针类型时,指针类型的值也是调用这个方法,反之亦然。

    内嵌类型的方法和继承

      当一个匿名类型被内嵌在结构体中时,匿名类型的可见方法也同样被内嵌,这在效果上等同于外层类型继承了这些方法,将父类型放在子类型中实现(子类型中的方法,可以直接使用父类型加点子类型方法的方式调用[father.childMethod()])

      但是当父类型和子类类型有相同名字的方法怎么办呢?父类型的方法会覆盖子类型的。

     1 package main
     2 
     3 import "fmt"
     4 
     5 type Child struct {
     6     a, b int
     7     Father// 【重点】这里必须是匿名类型才可以实现继承的效果,否则不可以!!!!!!
     8 }
     9 type Father struct {
    10     name string
    11 }
    12 
    13 func (fa *Father) GetName() (re string) {
    14     re = chi.name
    15     return
    16 }
    17 
    18 func main() {
    19     c := Child{1, 3, Father{"Kobe"}}
    20     fmt.Println(c.GetName())
    21 }
  • 相关阅读:
    gcc编译器
    samba服务器
    NFS服务器
    tftp服务器配置过程
    centos6.5下编译hello.ko驱动程序
    使用poi导出数据到excel
    使用poi根据模版生成word文档,支持插入数据和图片
    使用javaMail实现简单邮件发送
    outlook2016用Exchange轻松绑定腾讯企业邮箱
    Python Pyinstaller打包含pandas库的py文件遇到的坑
  • 原文地址:https://www.cnblogs.com/ymkfnuiwgij/p/8670134.html
Copyright © 2020-2023  润新知