接口 interface
接口声明了方法集合
如果某个结构体实现了接口内的所有方法, 就可以把该结构体赋值给接口
接口可以帮助我们实现类似面向对象的"类的继承"
package main
import (
"log"
)
// Abser 接口定义了方法集合
type Abser interface {
Abs() float64
}
// Vertex -
type Vertex struct {
X, Y float64
}
// Abs -
func (v *Vertex) Abs() float64 {
return v.X*v.X + v.Y*v.Y
}
func main() {
// 创建一个 Abser 接口变量 a
var a Abser
// 由于 *Vertex 实现了Abs(), 所以他实现了接口a的所有方法, 可以赋值给接口a
a = &Vertex{3, 5} // 正确, *Vertex 上实现了Abs()
// b = Vertex{3, 4} // 运行错误, Vertex 上没有实现Abs()
log.Println(a.Abs()) // 34
}
隐式接口
相当于合并了 其他接口的定义
package main
import (
"log"
"os"
)
// Reader 定义一个接口
type Reader interface {
Read(b []byte) (n int, err error)
}
// Writer 定义一个接口
type Writer interface {
Write(b []byte) (n int, err error)
}
// 隐式接口, 相当于合并了 其他接口的定义
type ReadWriter interface {
Reader
Writer
}
func main() {
var w ReadWriter
w = os.Stdout
log.Println(w) // &{0xc420098050}
log.Println(w.Read) // 0x10b1690
}
泛型: 使用接口作为函数的参数
package main
import "log"
// Point -
type Point struct {
x, y float64
}
// 接口作为参数
func anyParams(v interface{}) {
// 判断 v 是否可以转换为 int 类型
if f, ok := v.(int); ok {
log.Println(f)
}
// 判断 v 是否可以转换为 string 类型
if f, ok := v.(*Point); ok {
log.Println(f.x + f.y)
}
}
func main() {
anyParams(2) // 2
anyParams(&Point{100, 150}) // hello T
}
参数和返回值都是接口的例子
package main
import "log"
// 接口作为参数, 接口作为返回值
func anyBack(v interface{}) interface{} {
if f, ok := v.(int); ok {
end := f * f
return end
} else if f, ok := v.(string); ok {
end := f + f
return end
}
return v
}
func main() {
b1 := anyBack(200)
log.Println(b1) // 40000
b2 := anyBack("hello")
log.Println(b2) // hellohello
}
参考资料:
http://go-tour-zh.appspot.com/
https://blog.csdn.net/hyl999/article/details/76573378
网友评论