10月14日-16日,由CSDN和创新工场联合主办的 MDCC 2015中国移动开发者大会 将在北京新云南皇冠假日酒店隆重召开,现在抢注大会门票,即享多重好礼!
使用得当的话, 函数式编程 方式的确功能强大。尽管Java 8包含了一些函数式编程机制,可是你能够想象Android开发人员无法很快就能用上(甚至永远不能)。为解决这个问题,替代语言出现了。
函数式编程依赖于函数和不变性,这样调用一个函数始终会返回相同的结果。通常,折中既是完美,所以大多数现代开发语言(如: Kotlin 或Scala)都在一种开发语言中,融合了过程式编程和函数式编程方法,并在这两方面拥有最为精彩的灵感和创意。有些问题使用函数式编程方式解决更好,还有一些问题,坚持使用过程式编程方式解决则更直接。
Lambda表达式是定义匿名函数的简单形式。由于Lambda表达式避免了在抽象类和接口中编写明确的函数声明,进而也避免了类的实现部分,因此十分有用。在Kotlin中,可以使用函数作为另一个函数的参数。例如,可以将需要回调(callback)的函数简化为如下代码:
fun runAsync(callback: () -> Unit){ ... callback() }
这种用法十分直观。做一些转换后(稍后会看到),函数的调用方式可以得到简化:
runAsync { toast("Finished") }
另一个件让人赏心悦目的事情是,Kotlin使用单独的函数编写接口,这些接口就好像是Lambda表示式。这样就可以大规模地简化代码。举个例子来说更容易明白,想象一下,我们要为视图编写一个典型的setOnClickListener()方法:
使用Java语言编写的接口:
public interface OnClickListener { void onClick(View v); }
然后需要编写匿名类以实现该接口:
view.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { Toast.makeText(v.getContext(), "Click", Toast.LENGTH_SHORT).show(); } });
这可以转换为Kotlin代码(使用Anko 库函数toast):
view.setOnClickListener(object : OnClickListener { override fun onClick(v: View) { toast("Click") } })
如前所述,Kotlin允许对Java类库进行一些优化,任何具备接口的函数都可以用函数替代。就像定义了setOnclickListener()方法那样去工作:
fun setOnClickListener(listener: (View) -> Unit)
Lambda表达式由箭头左侧函数的参数(小括号里面的内容)定义的,将值返回给箭头右侧。在这里,将得到的View返回给Unit,了解了这些内容,可以对上述代码稍做简化:
view.setOnClickListener({ view -> toast("Click")})
真是微妙的差别啊!在定义函数时,必须在箭头左边使用中括号并指定参数值,而函数执行代码在右边。如果左边没有使用参数,甚至可以省去左边部分:
view.setOnClickListener({ toast("Click") })
如果被执行的函数是当前函数的最后一个参数的话,也可以将这个作为参数的函数放到圆括号外面:
view.setOnClickListener() { toast("Click") }
最后,如果函数是唯一的参数,还可以去掉原来的小括号:
view.setOnClickListener { toast("Click") }
比起起初的Java代码,目前的代码量小于原来的五分之一,且更容易理解。令人印象深刻。Anko给出一个(本质上说是函数名的)简化版本,由之前展示过的扩展函数组成,该函数也由上述形式实现::
view.onClick { toast("Click") }
幸亏有这些转换,可以创建自己的生成器和代码块。Kotlin标准库提供一些像with那样有趣的函数。下面是更简单的实现方式::
inline fun <T> with(t: T, body: T.() -> Unit) { t.body() }
这个函数会获取一个类型T的对象,还会获得一个函数,该函数被用作扩展函数。实现的过程仅仅解决了对象,并让对象执行函数。由于函数的第二个参数是另一个函数,所以可以将它放到括号外面。因此,可以直接创建代码块,也可以使用对象的this关键字,还能够直接使用公共属性和对象的函数:
with(forecast) { Picasso.with(itemView.ctx).load(iconUrl).into(iconView) dateView.text = date descriptionView.text = description maxTemperatureView.text = "${high.toString()}º" minTemperatureView.text = "${low.toString()}º" itemView.onClick { itemClick(forecast) } }
Lambda表达式的强大还仅依赖于我们的想象。如果没有使用过函数式编程方式的话,那么掌握Lambda表示式就还需要实践。这样做是不吃亏的。如果想要学习更多Lambda表达式和Kotlin语言的相关内容,从我 正在编写的书 中可以收获更多。
(翻译/张挥戈 友情审校/白云鹏)
文章来源: antonioleiva
作者简介: Antonio Leiva ,Android工程师、热爱用户体验、界面设计,目前就职于 Plex, Inc 。
译者简介:
张挥戈,长期从事计算机软件开发、项目管理和产品设计工作,曾在多家移动互联网公司任技术总监。关注Android平台相关技术以及其他平台客户端软件开发相关话题。
预告: 2015中国移动开发者大会(MDCC 2015) 将于10月14日-16日在北京新云南皇冠假日酒店召开。大会特设九大技术专场:平台与技术(iOS)、平台与技术(Android)、平台与技术(跨平台)、产品与设计、游戏开发、企业移动化、虚拟现实专场、硬件开发与技术、嵌入式开发。大会将聚集国内最具实力的产品技术团队,与开发者一道进行最前沿的探讨与交流。