Go圣经-学习笔记之方法


声明:本文转载自https://my.oschina.net/u/3287304/blog/1556388,转载目的在于传递更多信息,仅供学习交流之用。如有侵权行为,请联系我,我会及时删除。

上一篇 Go圣经-学习笔记之defer和异常处理

方法声明

方法是对象的行为,在OOP中,我们一般称对象是由属性集合和行为集合共同组成,通过其行为修改对象属性。在Go语言中,方法的声明是在普通函数名字前加一个变量类型,就是一个方法。例如:

func (p Point) Distance(q Point) float64 {     return math.Hypot(p.X-q.X, p.Y-q.Y) } 

上面DEMO,q是表示方法的接收器,在其他语言中就是this或者self,表示对象自身。在Go语言中,我们可以任意地选择接收器的名字,一般官方建议是采购结构体类型的第一个字母

基于指针对象的方法

当调用一个函数时,会对其每一个参数j进行拷贝,如果一个函数需要更新变量,或者函数的某个参数占内存空间比较大,避免大内存拷贝,我们这时候就需要指针了。对应到方法,就是要采用指针接收器。例如:

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

如果我们采用非指针对象修改对象的属性,如下:

type Person struct { 	Name string }  func (p Person) ModifyName(name string) { 	p.Name = name 	return }  func main() { 	var p = Person{Name: "chendonghai"} 	p.ModifyName("chenjixiang") 	fmt.Println(p.Name) } // 输出结果: /* chendonghai */ 

输出结果不是chenjixiang的原因,是Person类型的对象接受者不是指针对象,所以调用方法时,发生了拷贝,所以产生的对象修改都是临时对象属性值的修改。

关于对象接收者,这里有两点关于编译器优化的说明:

  • 如果对象接收者是指针类型数据,调用时使用的非指针对象,那么编译器会默认改为指针对象调用方法
  • 如果对象接收者是非指针类型数据,调用时使用了指针对象,那么编译器会把指针对象改为非指针对象调用。
func (p Point) Distance(q Point) float64 {     return 1.0 } var p = &Point{     ... } p.Distance(...) // 这编译器会把这个语句改为:(*p).Distance(...)  func (p *Point) Distance(q Point) float64 {     return 1.0 } var p = Point{     ... } p.Distance(...) // 则编译器会把指非指针对象改为指针对象: (&p).Distance(...) 

说到这里,就要提一个与C++不同的地方:

type Person struct {     Name string }  func (p *Person) GetName() string {     if p ==nil {         return ""     }     return p.Name }  func main(){     var p *Person     fmt.Println(p.GetName()) } 

C++ 这样做,必挂。它是通过vtable[]虚表做到的。在我写的最开始那篇文章,Go语言中不存在没有初始化的变量,每个数据类型数据都有对应的零值,比如:nil,所以调用时是合法的。C++叫做没有初始化的值。我在stackoverflow上提个这个问题,更具体,更权威的回答:nil值调用指针对象的方法

这个我经常遇到,例如:利用protoc生成Go语言版本的protocol buffer的数据模型文件,一定会存在。例如: nil值

go语言中,零值的类型数据读取时不会panic,引用类型、指针类型的零值写入时会panic。

本文发表于2017年10月26日 10:34
(c)注:本文转载自https://my.oschina.net/u/3287304/blog/1556388,转载目的在于传递更多信息,并不代表本网赞同其观点和对其真实性负责。如有侵权行为,请联系我们,我们会及时删除.

阅读 2298 讨论 0 喜欢 0

抢先体验

扫码体验
趣味小程序
文字表情生成器

闪念胶囊

你要过得好哇,这样我才能恨你啊,你要是过得不好,我都不知道该恨你还是拥抱你啊。

直抵黄龙府,与诸君痛饮尔。

那时陪伴我的人啊,你们如今在何方。

不出意外的话,我们再也不会见了,祝你前程似锦。

这世界真好,吃野东西也要留出这条命来看看

快捷链接
网站地图
提交友链
Copyright © 2016 - 2021 Cion.
All Rights Reserved.
京ICP备2021004668号-1