go学习-接口和反射

  • 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 的方法

你可能感兴趣的:(go学习-接口和反射)