GO 方法

作者: 舍是境界 | 来源:发表于2020-04-12 13:31 被阅读0次

    方法声明

    在函数声明时,在其名字之前放上一个变量,即是一个方法。这个附加的参数会将该函数附加到这种类型上,即相当于为这种类型定义了一个独占的方法。

    // same thing, but as a method of the Point type
     func (p Point) Distance(q Point) float64 {
         return math.Hypot(q.X-p.X, q.Y-p.Y)
    }
    

    附加的参数p,叫做方法的接收器(receiver)。

    基于指针对象的方法

    这个接受者变量本身比较大时,我们就可以用其指针而不是对象来声明方法

    func (p *Point) ScaleBy(factor float64) {
      p.X *= factor
      p.Y *= factor
    }
    

    这个方法的名字是(Point).ScaleBy
    只有类型(Point)和指向他们的指针(
    Point),才是可能会出现在接收器声明里的两种接收器。此外,为 了避免歧义,在声明方法时,如果一个类型名本身是一个指针的话,是不允许其出现在接收器中的

    type P *int
     func (P) f() { /* ... */ } // compile error: invalid receiver type
    

    在每一个合法的方法调用表达式中,不论是接收器的实际参数和其接收器的形式参数相同,比如两者都是类型T或者都是类型*T:

    Point{1, 2}.Distance(q) //  Point
     pptr.ScaleBy(2)         // *Point
    

    或者接收器形参是类型T,但接收器实参是类型*T,这种情况下编译器会隐式地为我们取变量的地址:

    p.ScaleBy(2) // implicit (&p)
    

    或者接收器形参是类型*T,实参是类型T。编译器会隐式地为我们解引用,取到指针指向的实际变量:

    pptr.Distance(q) // implicit (*pptr)  
    

    如果类型T的所有方法都是用T类型自己来做接收器(而不是*T),那么拷贝这种类型的实例就是安全的;

    通过嵌入结构体来扩展类型

    内嵌可以使我们定义字段特别多的复杂类型,我们可以将字段先按小类型分组,然后定义小类型的方法,之后再把它们组合起来。

    方法值和方法表达式

    我们经常选择一个方法,并且在同一个表达式里执行,比如常见的p.Distance()形式,实际上将其分成 两步来执行也是可能的。p.Distance叫作“选择器”,选择器会返回一个方法"值"->一个将方法 (Point.Distance)绑定到特定接收器变量的函数。这个函数可以不通过指定其接收器即可被调用;即调 用时不需要指定接收器(译注:因为已经在前文中指定过了),只要传入函数的参数即可:

    p := Point{1, 2}
     q := Point{4, 6}
     distanceFromP := p.Distance
     fmt.Println(distanceFromP(q))
     var origin Point
     fmt.Println(distanceFromP(origin))
    scaleP := p.ScaleBy // method value
    }
    scaleP(2)
    scaleP(3)
    scaleP(10)
    

    封装

    一个对象的变量或者方法如果对调用方是不可见的话,一般就被定义为“封装”。封装有时候也被叫做信息隐藏,同时也是面向对象编程最关键的一个方面。
    Go语言只有一种控制可见性的手段:大写首字母的标识符会从定义它们的包中被导出,小写字母的则不 会。这种限制包内成员的方式同样适用于struct或者一个类型的方法。因而如果我们想要封装一个对 象,我们必须将其定义为一个struct。

    封装的三方面有点

    1. 因为调用方不能直接修改对象的变量值,其只需要关注少量的语句并
      且只要弄懂少量变量的可能的值即可。
    2. 隐藏实现的细节,可以防止调用方依赖那些可能变化的具体实现,这样使设计包的程序员在不破 坏对外的api情况下能得到更大的自由。
    3. 阻止了外部调用方对对象内部的值任意地进行修改

    总结

    1. 方法是特殊的函数
    2. 方法的接受者可以是指针,但是指针类型的数据,不能作为接受者
    3. 方法值可以在使用方法时,更简短实用
    4. 封装的使用需要结合struct,更好的发挥面向对象的好处

    相关文章

      网友评论

          本文标题:GO 方法

          本文链接:https://www.haomeiwen.com/subject/nilvmhtx.html