effective go 中的部分笔记,这是第二部分
部分笔记摘要,参考: https://go-zh.org/doc/effective_go.html
方法/Methods
与一般的面向对象语言不同;一般的面向对象语言定义类,然后在类中定义属性和方法,通过类的继承来抽象一套机制,但是在Go中,首先是定义结构,然后为已经命名的结构(除了指针或接口)定义方法,这里有一个方法接收者的概念,为一个结构体绑定方法的常用用法如下:
type Book struct { |
对一些方法,传入的参数是值的拷贝而不是地址,经常需要在方法的结尾放回新的结果,可以通过把参数的指针传入,直接修改参数的地址指向的值,常见的io.Write接口就是在指针添加方法。
type byteSlice []byte |
以指针或值为接收者的区别在于:值方法可通过指针和值调用, 而指针方法只能通过指针来调用
接口与其他类型/interface
Go中的接口为指定对象的行为提供了一种方法:如果某样东西可以完成这个, 那么它就可以用在这里。我们已经见过许多简单的示例了;通过实现 String 方法,我们可以自定义打印函数,而通过 Write 方法,Fprintf 则能对任何对象产生输出。
Go中的的接口只是需要实现它的类接受了同名的方法即可,这是很特别的。
类型转换
下面的代码:
type squence []int |
如果忽略类型名,squence和[]int其实是相同的,只不过squence有一个新的类型名而已,所以在他们之间进行类型转换是可以的:
is := []int(s) |
在Go语言中,为了访问不同的方法集会经常进行类型转换。甚至对int和float之间的简单运算都会用到类型转换。
接口转换与类型断言
对于混合类型,我们经常需要将一种接口转换为另一种接口,要判断一个值是否实现了某个接口,需要使用到类型断言。类型断言接受一个接口值,并从中提取指定的明确的明确类型的值。与其他语言判断类型不同,它的用法如下:
var.(typeName) |
这是一个看起来很奇怪的用法,不知道Go中有没有提供想instanceof这样的关键字。
通用性/Generality
这部分还不是很了解
若某种现有的类型仅实现了一个接口,且除此之外并无可导出的方法,则该类型本身就无需导出。 仅导出该接口能让我们更专注于其行为而非实现,其它属性不同的实现则能镜像该原始类型的行为。 这也能够避免为每个通用接口的实例重复编写文档。
在这种情况下,构造函数应当返回一个接口值而非实现的类型。
接口和方法
Go中几乎任何类型(除了指针和接口)都能添加方法(添加的示例已经看过很多了,就不赘述了),因此几乎任何类型都能满足一个接口(即使是基于int的类型也能用来满足一个特别的接口),常见的用法就是任何实现了ServeHTTP方法的对象都能处理HTTP请求。
甚至可以为func添加方法,当然需要先将函数定义为一种新类型
Handler接口定义如下:
type Handler interface { |
下面是一个实现该接口的示例:
import "net/http" |
当然也可以绑定到一个信道上面,然后使用信道新更新一些内部状态:
type Chan chan *http.Request |