Go语言圣经 - 第6章 方法 - 6.4 方法值和方法表达式

第6章 方法

从90年代开始,面向对象编程(OOP)就成了称霸工程界和教育界的编程范式,所以之后几乎所有大规模被应用的语言都包含了对OOP的支持,Go语言也不例外

关于OOP,其实没有明确定义,但是大概的意思是,一个对象其实也就是一个简单的值或者一个变量,在这个对象中会包含一些方法,而一个方法则是一个一个和特殊类型相关联的函数,一个面向对象的程序会用方法来表达其属性和对应的操作,这样使用这个对象的用户就不需要直接去操作对象,而是借助方法来做这些事情

在早些章节,其实我们已经使用过标准库提供的一些方法,比如time.Duration这个类型的Seconds方法

const day = 24*time.Hour
fmt.Println(day.Seconds())//86400

在2.5节中,我们定义了一个方法,Celsius类型的String方法

func (c Celsius) String() string{
   return fmt.Sprintf("%g˚C",c)
}

在本章中,OOP编程的第一方面,我们会展示如何有效的定义和使用方法,我们会覆盖到OOP编程的两个关键点,封装和组合

6.4 方法值和方法表达式

我们经常选择一个方法,并在同一个表达式里执行,比如常见的p.Distacne()形式,实际上将其分成两部分执行也行的。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))

scalP := p.ScaleBy
scalP(2)
scalP(3)
scalP(10)

在一个包的API需要一个函数值、且调用方希望操作的是某一个绑定了对象的方法的话,“方法值”非常有用,例如time.Func这个函数的功能是在指定到延迟时间之后来执行一个函数,且这个函数操作的是一个Rocket对象r

type Rocket struct{/* ... */}
func (r *Rocket)lunch(){
r := new(Rocket)
time.After(10*time.Second,func(){r.lunch()})

直接用方法“值”传入AfterFunc的话可以更简短

time.AfterFunc(10*time.Second,r.Launh)

注意:省略掉了上面的匿名函数

和方法“值”相关的还有方法表达式:与调用一个普通的函数相比,调用方法时,我们必须要选用选择器(p.Distance)语法来指定方法的接收器

当T是一个类型时,方法表达式可能会写成T.f或者(*T).f,会返回一个函数“值”,这种函数会将其第一个参数用作接收器,所以可以用不写选择器的方式来对其进行调用

p:=Point{1,2}
q:=Point{4,6}

distance := Point.Distance
fmt.Println(distance(q,p))//5 好像变回了调用函数一样
fmt.Printf("%T\n",distance)//func(main.Point, main.Point) float64

scale := (*Point).ScaleBy
	scale(&p,2)
	fmt.Println(p) // {2 4}
	fmt.Printf("%T\n",scale)  //func(*main.Point, float64)

当你根据一个变量来决定调用同一个类型的哪个函数时,方法表达式就显得很有用了,你可以根绝选择来调用接收器各不相同的方法,在下例中,变量op代表Point类型的Add或者Sub方法,Path.TranslateBy方法会为其Path数组中的每一个Point来调用对应的方法

type Point struct {X,Y float64}

func (p Point) Add(q Point) Point{return Point{p.X+q.X,p.Y+q.Y}}
func (p Point) Sub(q Point) Point{return Point{p.X-q.X,p.Y-q.Y}}

type Path []Point

func (path Path) TranslateBy (offset Point,add bool) {
   var op func(p,q Point) Point
   if add{
      op = Point.Add
   }else {
      op = Point.Sub
   }
   for i := range path{
      path[i] = op(path[i],offset)
   }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言圣经》是一本广受好评的教材,旨在帮助读者系统地学习和掌握Go语言。这本书以简明清晰的方式介绍了Go语言的各种特性、语法和用法,是入门和进阶者的理想选择。 首先,该书提供了对Go语言基础知识的全面介绍。它从简单到复杂地解释了Go语言的基本概念,诸如变量、函、循环和条件语句等等。通过丰富的例子和练习,读者能够逐步理解和掌握这些概念。 其次,该书详细介绍了Go语言的高级特性和用法。读者可以学习到Go语言的面向对象编程、并发编程、网络编程等关键技术。并发编程是Go语言的一个独特特性,对于提高程序性能和扩展能力非常重要。 此外,该书还包含了对常见问题和陷阱的讲解,帮助读者避免一些常见的错误和陷阱。同时,书中提供了大量的案例和实践项目,读者可以通过实际操作来巩固所学内容。 《Go语言圣经》以其简洁明了的风格和对细节的深入讲解而闻名。无论是作为初学者的入门指南,还是作为有经验的开发者的参考书,这本书都能满足读者的需求。此外,该书的PDF版本能够方便地在线或离线阅读,为读者提供了更加便捷的学习体验。 综上所述,《Go语言圣经》是一本内容丰富、权威性强的优秀教材。它不仅适合Go语言的初学者,也适用于那些想要深入学习和掌握Go语言开发者。无论是在线阅读还是PDF版本,读者都能够方便地获取和利用这本宝贵的学习资源。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值