释放Android的函数式能量(I):Kotlin语言的Lambda表达式
2015-12-05 16:00
525 查看
原文标题: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语言的另一个出色方面是,允许用lambda表达式编写接口,这样可以巨大地简化代码。举例说明更易明白,假设要编写视图的典型setOnClickListener()方法。
在Java语言中,接口代码类似这样:
然后,需要编写匿名类实现这个接口:
这段代码转换到Kotlin语言(用Anko
如前所述,Kotlin语言允许对Java语言类库进行一些优化,任何有接口的函数都可以由函数替代。就像定义setOnclickListener()方法那样去运行:
Lambda表达式由箭头左侧函数的参数(在圆括号里的内容)定义的,将值返回到箭头右侧。在这个例子中,得到的
美妙的差异!在定义函数时,必须在箭头的左侧用方括号,并指定参数值,而函数的执行代码在箭头右侧。如果左侧不使用参数,甚至可以省去左侧部分:
如果函数的最后一个参数是一个函数的话,可以将作为参数的函数移到圆括号外面:
最终,如果函数是唯一的参数,还可以去掉圆括号:
与初期的Java语言代码相比,代码量小于原来的五分之一,且更容易理解。这实在是令人印象深刻。Anko给一个(本质上说是函数名的)简化版本,由前面展示过的实现方法的扩展函数组成:
这个函数会获取一个类型T的对象和作为扩展函数使用的函数。实现的过程仅仅解决了对象,并让对象执行函数。由于函数的第二个参数是另一个函数,所以可以将其移到括号外面。这样可以直接使用对象的
原文链接: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开发者文档笔记(一)
- Android中Bitmap和Drawable
- android(24)(用java实现多线程断点下载)
- android下面的文案重用
- Android 布局 LinearLayout与RelativeLayout的布局属性
- ListView实现公告切换效果
- Android推送通知
- android自定义ProgressBar 修改进度条样式 出现setProgress无效问题
- android电话监听实现
- 10 条提升 Android 性能的建议
- 【转载】Android样式的开发:Style篇
- android 提高进程的优先级
- android通过泛型获取控件或视图
- android典型代码系列(二十一)------根据文件后缀名获得对应的MIME类型
- android 自定义流布局。实现热门标签。开源库SimpleFlowLayout
- 【转载】Android屏幕适配全攻略(最权威的官方适配指导)
- Android 高仿 QQ5.0 侧滑菜单效果 自定义控件来袭
- Android之可以做的两件坏事---破解锁屏密码和获取Wifi密码
- Android Studio 下使用assets文件夹心得
- android 内存泄漏