1、概述
-
接口写法
type ReadWriter interface { //混合写法 Read(p []byte) (n int, err error) //正常方法声明 Writer //接口内嵌 }
-
表达一个类型属于某个接口只要这个类型实现这个接口(所有方法)
-
因为空接口类型interface{} 对实现它的类型没有要求,所以我们可以将任意一个值赋给空接口类型。
-
Flag用法:golang flag包使用笔记
2、接口值
- 对于一个接口的零值就是它的类型和值的部分都是nil,可以通过使用w==nil或者w!=nil来判读接口值是否为空。
- 调用一个空接口值上的任意方法都会产生panic。
- 当接口被赋值为一个具体的实例,这个接口值的动态类型被设为实例指针的类型描述符,它的动态值持有实例的拷贝;这是一个代表被赋值的实例类型变量的指针
- 一个包含 nil 指针的接口不是 nil 接口,参考:文章__过来参考啊
3、部分常用接口
1、sort接口
接口定义:
package sort
type Interface interface {
Len() int //比较数组长度
Less(i, j int) bool // i, j are indices of sequence elements //比较规则
Swap(i, j int) //交换方式
}
接口使用:
1、实现sort接口,实现是三个方法,比如说Mysort。
2、通过sort.Sort(Mysort(myList))
调用对应的实现方法(入参为排序数组)
实现自定义排序:
1、创建一个结构体,实现sort接口,实现三个方法,比如说CutomerSort
2、调用sort接口进行排序,在customSort中定义自己的排序规则
sort.Sort(customSort{myList, func(x, y *listType) bool {
if {
} //规则1
if {
} //规则2
if {
} //规则3
return false
}})
2、http.Handler接口
参考原文
3、error接口
接口声明
package errors
func New(text string) error { return &errorString{text} }
type errorString struct { text string }
func (e *errorString) Error() string { return e.text }
error类型设计的原因
承载errorString的类型是一个结构体而非一个字符串,这是为了保护它表示的错误避免粗心(或有意)的更新。并且因为是指针类型*errorString满足error接口而非errorString类型,所以每个New函数的调用都分配了一个独特的和其他错误不相同的实例。
4、类型断言
类型断言写法:
var w io.Writer = os.Stdout
f, ok := w.(*os.File) // success: ok, f == os.Stdout
b, ok := w.(*bytes.Buffer) // failure: !ok, b == nil
当类型断言的操作对象是一个变量,你有时会看见原来的变量名重用而不是声明一个新的本地变量,这个重用的变量会覆盖原来的值
if w, ok := w.(*os.File); ok {
// ...use w...
}
类型断言识别错误类型
通过不同的错误,实现error接口,在发生错误的时候,判断error的类型来提示不同的报错。具体查看原文
5、使用建议
- 有很多的接口,它们中的每一个仅只有一个实现。这种接口是不必要的抽象;它们也有一个运行时损耗。你可以使用导出机制来限制一个类型的方法或一个结构体的字段是否在包外可见。接口只有当有两个或两个以上的具体类型必须以相同的方式进行处理时才需要。
- 当一个接口只被一个单一的具体类型实现时,由于它的依赖,这个具体类型不能和这个接口存在在一个相同的包中。这种情况下,一个接口是解耦这两个包的一个好方式。