玩命加载中 . . .

7-接口


只要一个类里面实现了接口里的方法,就可以将接口和类的实例绑定,并调用对应类的方法实现

type Sleeper interface {
    Sleep()
}

type Dog struct {
    Name string
}

func (d Dog) Sleep() {
    fmt.Printf("Dog %s is sleeping\n", d.Name)
}

type Cat struct {
    Name string
}

func (c Cat) Sleep() {
    fmt.Printf("Cat %s is sleeping\n", c.Name)
}

func AnimalSleep(s Sleeper) {
    s.Sleep()
}

func test1() {
    var s Sleeper
    dog := Dog{Name: "小白"}
    cat := Cat{Name: "kitty"}
    s = dog     // 接口绑定到dog
    AnimalSleep(s)

    s = cat     // 接口绑定到cat
    AnimalSleep(s)

    // 也可以定义成slices
    sleepList := []Sleeper{
        Dog{Name: "小黑"},
        Cat{Name: "Kitty"},
    }

    for _, s := range sleepList {
        s.Sleep()
    }
}
// Dog 小白 is sleeping
// Cat kitty is sleeping
// Dog 小黑 is sleeping
// Cat Kitty is sleeping

接口嵌套

接口可以嵌套
也可以用类型断言判断绑定的是什么类型

type Sleeper interface {
    Sleep()
}

type Eater interface {
    Eat(foodName string)
}

type LazyAnimal interface {
    Sleeper     // 接口嵌套
    Eater
}

type Dog struct {
    Name string
}

func (d Dog) Sleep() {
    fmt.Printf("Dog %s is sleeping\n", d.Name)
}

func (d Dog) Eat(foodName string) {
    fmt.Printf("Dog %s is eating %s\n", d.Name, foodName)
}

type Cat struct {
    Name string
}

func (c Cat) Sleep() {
    fmt.Printf("Cat %s is sleeping\n", c.Name)
}

func (c Cat) Eat(foodName string) {
    fmt.Printf("Cat %s is eating %s\n", c.Name, foodName)
}

func AnimalSleep(s Sleeper) {
    s.Sleep()
}

func test2() {
    sleepList := []LazyAnimal{
        Dog{Name: "小黑"},
        Cat{Name: "Kitty"},
    }

    for _, s := range sleepList {
        s.Sleep()
        s.Eat("food")

        // 类型断言 type assert
        if dog, ok := s.(Dog); ok {
            fmt.Printf("I am a Dog, my name is %s\n", dog.Name)
        }
        if cat, ok := s.(Cat); ok {
            fmt.Printf("I am a Cat, my name is %s\n", cat.Name)
        }
    }
}
// Dog 小黑 is sleeping
// Dog 小黑 is eating food
// I am a Dog, my name is 小黑
// Cat Kitty is sleeping
// Cat Kitty is eating food
// I am a Cat, my name is Kitty

空接口

任何类型都可以转换为空接口

func test3() {
    // 空接口
    animalList := []interface{}{
        Dog{Name: "小黑"},
        Cat{Name: "Kitty"},
    }

    for _, s := range animalList {
        // 类型断言 type assert
        if dog, ok := s.(Dog); ok {
            fmt.Printf("I am a Dog, my name is %s\n", dog.Name)
        }
        if cat, ok := s.(Cat); ok {
            fmt.Printf("I am a Cat, my name is %s\n", cat.Name)
        }
    }
}
// I am a Dog, my name is 小黑
// I am a Cat, my name is Kitty

用空接口接收各种类型,根据类型调用对应方法

func MyPrint(i interface{}) {
    switch o := i.(type) {
    case int:
        fmt.Printf("%d\n", o)
    case float64:
        fmt.Printf("%f\n", o)
    case string:
        fmt.Printf("%s\n", o)
    default:
        fmt.Printf("%+v\n", o)
    }
}

func test4() {
    MyPrint(42)
    MyPrint(3.14)
    MyPrint("kavin")
    MyPrint(map[string]int{"kavin": 23})
}
// 42
// 3.140000
// kavin
// map[kavin:23]

文章作者: kunpeng
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 kunpeng !
  目录