这个问题我不知道该怎样描述,大致意思是,我有一组函数,我想根据传入的名称来确定到底应该执行哪一个函数。当然,可以写像switch或者 是if else这样的语句进行判断,但是,总觉得这样写太俗,虽然能够达到预期的结果,但是代码看起来相当不美观。其实,原来我只是在乎功能,也不会很在意别人看我代码的感受,更不要说可维护性了。只是,近期,组里经常进行代码走查,我那代码五天走了三次,其中这五天还包括了周六日(当然,周六日是正常休息的,我的意思是,代码走查很频繁)每次代码走查,大家都会给我提好多意见,然后最后就总有一种感觉:我这几天白忙活了,所有代码都被否定了。当然,每次code review之后,也有很多收获。组里共四个人,他们三个都是编程经验丰富的高手,就我菜鸟一只,所以,我有很多师傅可以请教呀。他们三个都很好,我遇到不理解的问题,就可着劲的问,每次都说,你能不能讲得现实点。最后都会问到实现细节上。所以,虽然代码经常被否决,我却可以在很短的时间内重整旗鼓,重新组织代码。我现在追求的不再只是功能完善,而是上了一个台阶,要可读性强,结构清晰。貌似说远了哈,继续刚才的问题。如果碰到这种需要比较出结果的,在go中,我们首先想到的当然是map,有一个key值,我就有可能给找一个value值。所以,今天的主题就是讲函数作为map中的value.
package mainimport ( "fmt")type myfunc func(x, y int)func add(x, y int) { fmt.Println(x + y)}func minus(x, y int) { fmt.Println(x - y)}func multiply(x, y int) { fmt.Println(x * y)}var mapfunc = map[string]myfunc{ "add": add, "minus": minus, "multiply": multiply,}func main() { param := "minus" a, b := 5, 7 if ff, ok := mapfunc[param]; ok { ff(a, b) }}
上述代码是一个比较简单的例子,目的就是说明做法。关键的是要定义一个函数变量,这个貌似与C中的函数指针有些像,type myfunc func(x,y int),函数的形式是用户自定义的,入参还有返回值,自己定义。其实,可以将这个函数定义看做是一个接口,在GO中,一个类实现了一个接口不需要显式定义,只要是实现了这些接口,编译器会知道。同样的,在本例中,你自定义的函数可以随便命名,只要入参还有返回值与定义中的相同便可以了。最开始的时候,我还有一个疑惑,那参数是怎样传递过去的呢?后来想想,函数都拿到了,何愁参数怎样传进去呢,直接跟上就ok了呀。
今天同事还问我这个事,结果,他给出了更好的方案,不用map,而是用数组,将字符串映射到整数上,直接拿着索引去数组中找函数,还免去了搜索,一步到位,不得不承认,姜还是老的辣,虽然是很小的一部分,也要力求做到极致。