-
1、接口和它的实现 可以不在一个包里,也无先后顺序之分;
-
2、类型的实例可以赋值给接口的实例,如果该接口有方法集,则类型必须实现所有的方法集方可进行赋值。
package pkg1
// 定义一个包含两个方法的接口类型
type Simpler interface {
Get() int
Put(int)
}
type Simple struct {
i int
}
// 实现 Get方法
func (p *Simple) Get() int {
return p.i
}
// 实现 Put方法
func (p *Simple) Put(u int) {
p.i = u
}
// 以 接口Simpler为参数的函数
func fI(it Simpler) int {
it.Put(5)
return it.Get()
}
func main() {
var s Simple
fmt.Println( fI(&s) ) // 这里要注意:因为结构体 Simple实现了 接口Simpler的所有方法,所以它的指针指向接口Simpler。
}
一、类型断言
由于一个接口类型的变量可以包含任意类型的结构,所以需要有一种方式检查它的 动态 类型。
1、判断是否是特定类型
v , ok = interf.(T)
v:对应于类型T
ok:校验是否通过
type Shaper interface {
Area() float32
}
type Square struct {
side float32
}
func main() {
var areaIntf Shaper
sq1 := new(Square)
sq1.side = 5
areaIntf = sq1
if t, ok := areaIntf.(*Square); ok {
fmt.Printf("The type of areaIntf is: %T\n", t) // The type of areaIntf is: *main.Square
}
}
2、type-switch
有时候我们并不知道接口变量具体是什么类型,我们可以用 type-switch
来判断
switch areaIntf.(type) {
case string:
fmt.Printf("type is string\n")
case bool:
fmt.Printf("type is boolean\n")
case *Square:
fmt.Printf("type is Square\n")
case *Circle:
fmt.Printf("type is Circle\n")
default:
fmt.Println("没有匹配项")
}
3、方法集和接口
Go 语言规范定义了接口方法集的调用规则:
- 类型 *T 的可调用方法集包含接受者为 *T 或 T 的所有方法集
- 类型 T 的可调用方法集包含接受者为 T 的所有方法
- 类型 T 的可调用方法集不包含接受者为 *T 的方法
网友评论