go学习之方法关联到类型func(f *file)method()int{}

很多人可能跟我一样疑惑,为什么go的方法关键字会跟上(f *file),而file是struct结构,我们来看下【Go语言高级编程】这本书是怎么样讲解的?

方法

方法一般是面向对象编程(OOP)的一个特性,在C++语言中方法对应一个类对象的成员函数,是关联到具体对象上的虚表中的。但是Go语言的方法却是关联到类型的,这样可以在编译阶段完成方法的静态绑定。
面向对象编程更多的只是一种思想,下面我们实现一组C语言风格的File函数:

// 文件对象
type File struct {
    fd int
}

// 打开文件
func OpenFile(name string) (f *File, err error) {
    // ...
}

// 关闭文件
func CloseFile(f *File) error {
    // ...
}

// 读文件数据
func ReadFile(f *File, int64 offset, data []byte) int {
    // ...
}

其中OpenFile类似构造函数用于打开文件对象,CloseFile类似析构函数用于关闭文件对象,ReadFile则类似普通的成员函数,这三个函数都是普通的函数。CloseFile和ReadFile作为普通函数,需要占用包级空间中的名字资源。不过CloseFile和ReadFile函数只是针对File类型对象的操作,这时候我们更希望这类函数和操作对象的类型紧密绑定在一起。

Go语言中的做法是,将CloseFile和ReadFile函数的第一个参数移动到函数名的开头:

// 关闭文件
func (f *File) CloseFile() error {
    // ...
}

// 读文件数据
func (f *File) ReadFile(int64 offset, data []byte) int {
    // ...
}

这样的话,CloseFile和ReadFile函数就成了File类型独有的方法了(而不是File对象方法)。它们也不再占用包级空间中的名字资源,同时File类型已经明确了它们操作对象,因此方法名字一般简化为Close和Read:

// 关闭文件
func (f *File) Close() error {
    // ...
}

// 读文件数据
func (f *File) Read(int64 offset, data []byte) int {
    // ...
}

方法是由函数演变而来,只是将函数的第一个对象参数移动到了函数名前面了而已。因此我们依然可以按照原始的过程式思维来使用方法。通过叫方法表达式的特性可以将方法还原为普通类型的函数:

// 不依赖具体的文件对象
// func CloseFile(f *File) error
var CloseFile = (*File).Close

// 不依赖具体的文件对象
// func ReadFile(f *File, int64 offset, data []byte) int
var ReadFile = (*File).Read

// 文件处理
f, _ := OpenFile("foo.dat")
ReadFile(f, 0, data)
CloseFile(f)

参考文档:
https://books.studygolang.com/advanced-go-programming-book/ch1-basic/ch1-04-func-method-interface.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值