Go-函数式接口

在Java中,一切皆Object,在GO,一切皆type。


函数func也是一种type,只不过有点特殊:1、要先为func定义type;2、使用前必须将func转换为type。

如果func定义了type,并实现了接口,则为函数式接口。


下面以学生使用中英文自我介绍为例。

package main

import "fmt"
//定义一个接口,用于自我介绍
type introduce interface {
    say(name string, age int)
}

//定义introduceFunc类型,所有形参依次为string 、int 且返回为空的的函数都为introduceFunc类型
type introduceFunc func(name string, age int)

//introduceFunc类型实现接口introduce
func (f introduceFunc) say(name string, age int) {
    f(name, age)
}

//函数chineseSay,用中文自我介绍,形参依次为string 、int 且返回为空,所以,是introduceFunc类型
func chineseSay(name string, age int) {
    fmt.Printf("大家好,我叫%s,今年%d岁\n", name, age)
}

//函数chineseSay,用英文自我介绍,形参依次为string 、int 且返回为空,所以,是introduceFunc类型
func englishSay(name string, age int) {
    fmt.Printf("hi everyone,My name is %s,and I'm %d years old\n", name, age)
}

//遍历学生集合,每个学生自我介绍,具体自我介绍方式(用中文还是英文)取决于实参类型
func each(m map[string]int, h introduce) {
    if m != nil && len(m) > 0 {
        for name, age := range m {
            h.say(name, age)
        }
    }
}
func main() {
   students := map[string]int{"hu": 12, "lee": 33, "jim": 31}

   var handler introduceFunc = chineseSay
   each(students, handler)
   handler = englishSay
   each(students,handler)

   //以下编译错误,因为未将函数转换为对应类型
   //each(students,chineseSay)
}

输出如下:

大家好,我叫lee,今年33岁

大家好,我叫jim,今年31岁

大家好,我叫hu,今年12岁

hi everyone,My name is hu,and I'm 12 years old

hi everyone,My name is lee,and I'm 33 years old

hi everyone,My name is jim,and I'm 31 years old

上例假如不使用函数式接口,就得定义2个struct:EnglishSay,ChineseSay。然后定义method:say,也就是实现接口introduce。使用前创建struct实例。代码如下:

package main

import "fmt"
//定义一个自我介绍的接口
type introduce2 interface {
    say(name string, age int)
}
type ChineseSay struct {

}
func (ChineseSay) say(name string, age int) {
    fmt.Printf("大家好,我叫%s,今年%d岁\n", name, age)
}
type EngliseSay struct {

}
func (EngliseSay) say(name string, age int) {
    fmt.Printf("hi everyone,My name is %s,and I'm %d years old\n", name, age)
}

//遍历学生集合,每个学生自我介绍,具体自我介绍方式(用中文还是英文)取决于实参类型
func each2(m map[string]int, h introduce2) {
    if m != nil && len(m) > 0 {
        for name, age := range m {
            h.say(name, age)
        }
    }
}

func main() {
    students := map[string]int{"hu": 12, "lee": 33, "jim": 31}

    each2(students,ChineseSay{})
    each2(students,EngliseSay{})
}

输出结果如下:

大家好,我叫jim,今年31岁

大家好,我叫hu,今年12岁

大家好,我叫lee,今年33岁

hi everyone,My name is hu,and I'm 12 years old

hi everyone,My name is lee,and I'm 33 years old

hi everyone,My name is jim,and I'm 31 years old