释放Android的函数式能量(I):Kotlin语言的Lambda表达式
原文标题:Unleash functional power on Android (I): Kotlin lambdas
原文链接:http://antonioleiva.com/operator-overloading-kotlin/
原文作者:Antonio Leiva(http://antonioleiva.com/about/)
原文发布:2015-09-01

虽然Java 8中已包含一些函数式工具,且如你想象那样Android开发者还不能够立即(或许甚至根本不能)使用这些工具,但是如果恰当地使用,函数式编程依然是十分强的工具。为此许多其他编程语言正开始进行解决这个问题。
现代编程语言的函数式编程
由于函数式编程依赖于函数和永恒性,所以函数调用总是返回相同的结果。通常,完美是在各方合理的平衡点上,所以大多数现代编程语言,如Kotlin或Scala,都在单一编程语言中,融合过程式编程和函数式编程方法,并在这两方面拥有最为先进的理念。有些问题用函数式编程来解决更合适,而有些沿用过程式编程更直接。
在Android中用Kotlin语言实现Lamba表达式
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") }
扩展编程语言
多亏有这些转换,可以创建自己的生成器(builder)和代码块。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表达式和Kotlin相关内容,可从我编写的书中获得。
释放Android的函数式能量(I):Kotlin语言的Lambda表达式的更多相关文章
- Java 终于有 Lambda 表达式啦~Java 8 语言变化——Lambda 表达式和接口类更改【转载】
原文地址 en cn 下载 Demo Java™ 8 包含一些重要的新的语言功能,为您提供了构建程序的更简单方式.Lambda 表达式 为内联代码块定义一种新语法,其灵活性与匿名内部类一样,但样板文件 ...
- Kotlin函数与Lambda表达式深入
Kotlin函数: 关于Kotlin函数在之前也一直在用,用fun来声明,回忆下: 下面再来整体对Kotlin的函数进行一个学习. 默认参数(default arguments): 先来定义一个函数: ...
- Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)
作者:Antonio Leiva 时间:Jan 5, 2017 原文链接:https://antonioleiva.com/lambdas-kotlin/ 由于Lambda表达式允许更简单的方式建模式 ...
- 《疯狂Kotlin讲义》读书笔记6——函数和Lambda表达式
函数和Lambda表达式 Kotlin融合了面向过程语言和面向对象语言的特征,相比于Java,它增加了对函数式编程的支持,支持定义函数.调用函数.相比于C语言,Kotlin支持局部函数(Lambda表 ...
- 深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-language- ...
- [转]深入理解Java 8 Lambda(语言篇——lambda,方法引用,目标类型和默认方法)
以下内容转自: 作者:Lucida 微博:@peng_gong 豆瓣:@figure9 原文链接:http://zh.lucida.me/blog/java-8-lambdas-insideout-l ...
- Lambda语言篇 —— lambda, 方法引用, 目标类型和默认方法
本文介绍了Java SE 8中新引入的lambda语言特性以及这些特性背后的设计思想.这些特性包括: lambda表达式(又被成为"闭包"或"匿名方法") 方法 ...
- C# 函数式编程 —— 使用 Lambda 表达式编写递归函数
最近看了赵姐夫的这篇博客http://blog.zhaojie.me/2009/08/recursive-lambda-expressions.html,主要讲的是如何使用 Lambda 编写递归函数 ...
- [二] java8 函数式接口详解 函数接口详解 lambda表达式 匿名函数 方法引用使用含义 函数式接口实例 如何定义函数式接口
函数式接口详细定义 package java.lang; import java.lang.annotation.*; /** * An informative annotation type use ...
随机推荐
- jexus5.8.2 linux x64专业版 配置https
一.环境 1.jexus版本:Jexus/5.8.2.8 Linux专业版 内置mono版本:Mono/4.6.2.7 2.操作系统:centOs7 jexus独立版由于是免安装版并且内置mono,所 ...
- 【深入浅出jQuery】源码浅析2--奇技淫巧
最近一直在研读 jQuery 源码,初看源码一头雾水毫无头绪,真正静下心来细看写的真是精妙,让你感叹代码之美. 其结构明晰,高内聚.低耦合,兼具优秀的性能与便利的扩展性,在浏览器的兼容性(功能缺陷.渐 ...
- 一文搞懂HMM(隐马尔可夫模型)
什么是熵(Entropy) 简单来说,熵是表示物质系统状态的一种度量,用它老表征系统的无序程度.熵越大,系统越无序,意味着系统结构和运动的不确定和无规则:反之,,熵越小,系统越有序,意味着具有确定和有 ...
- datepickerx设置默认日期
datepicher插件是jQuery UI的一个插件,它提供一个日期弹出窗口(或直接显示在页面),供用户选择日期.在Web开发中,总会遇到需要用户输入日期的情况.一般都是提供一个text类型的inp ...
- 学习笔记之(console)
今天小颖在逛博客园时,发现一位帅锅写的有意思的Console小颖看了后,就自己敲了一遍嘻嘻,为了方便以后查看,小颖把它记录下来嘻嘻,有兴趣的小伙伴也可以自己试试哦. 格式占位符 作用 %s 字符串 % ...
- spring 多数据源一致性事务方案
spring 多数据源配置 spring 多数据源配置一般有两种方案: 1.在spring项目启动的时候直接配置两个不同的数据源,不同的sessionFactory.在dao 层根据不同业务自行选择使 ...
- 匹夫细说C#:庖丁解牛聊委托,那些编译器藏的和U3D给的
0x00 前言 由于工作繁忙所以距离上一篇博客已经过去一个多月的时间了,因此决心这个周末无论如何也得写点东西出来,既是总结也是分享.那么本文主要的内容集中在了委托的使用以及内部结构(当然还有事件了,但 ...
- CloudNotes之桌面客户端篇:笔记撰写样式的支持
最近在CloudNotes桌面客户端中新增了笔记撰写样式的功能.当用户新建笔记的时候,可以在输入笔记标题的同时,选择笔记撰写样式,由安装包默认提供的样式主要有默认样式(Default).羊皮纸样式(L ...
- AJAX(一)
AJAX(一) Ajax是Asynchronous Javascript和XML的简写,这一技术能够向服务器请求额外的数据而无需卸载页面,会带来更好的用户体验. [前面的基础知识][关于同步和异步的了 ...
- Effective前端5:减少前端代码耦合
什么是代码耦合?代码耦合的表现是改了一点毛发而牵动了全身,或者是想要改点东西,需要在一堆代码里面找半天.由于前端需要组织js/css/html,耦合的问题可能会更加明显,下面按照耦合的情况分别说明: ...