首页 > 代码库 > Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)

作者:Antonio Leiva

时间:Jan 5, 2017

原文链接:https://antonioleiva.com/lambdas-kotlin/

技术分享

 

 

由于Lambda表达式允许更简单的方式建模式函数,所以它是Kotlin和任何其他现代开发语言的最强工具之一。

 

在Java6中,我们仅能下面方法这样做:通过用单一方法声明接口,并用匿名对象实现那些接口。

 

Lambda表达式特别是在Kotlin中能定义的方式,为我们开启无线可能的世界。在接下来的内容中,我们将了解这些用法。

 

Kotlin的Lambda表达式

 

Lambda表达式是函数的表示的方式,在解释setOnClickListener时,我们已经见过这个例子:

1 val view = findViewById(R.id.welcomeMessage)
2 view.setOnClickListener { v -> navigateWithView(v) }

 

如你所见,左边定义函数(在这个例子中时view)的输入值,右边声明函数要实现的操作。

 

怎样定义接受Lambda表达式的函数

 

如果我们自己要在Kotlin中定义函数,我们就需要按如下做法:

1 fun setOnClickListener(listener: (view: View) -> Unit){}

 

由于这个函数通过参数接收一函数,或返回一函数,所以,这是一高阶函数

 

Kotlin和Java interop

 

调用这个函数的一般方式可能是如下:

1 view.setOnClickListener({ v -> navigateWithView(v) })

 

这是我们已经见到这样做的比较简单的方法,而后续我们还能知道它帮助我们做更酷的事。

 

 

这是由于如果函数的最后一个参数是函数,我们能够将它从括号中提取出来:

1 view.setOnClickListener(){ v -> navigateWithView(v) }

 

另外,如果只有一个函数作为参数,我们还能省去括号:

1 view.setOnClickListener { v -> navigateWithView(v) }

 

DSL创建

 

这允许我们创建自己的DSL,这能定义微型语言。在Kotlin参考网站有HTML例子,而这里我们要定义一个更简介方法。

 

 

假设你要创建在另一个线程上运行的代码块。你可以有一个函数,它接收在后台运行的一个函数:

1 fun doAsync(f: () -> Unit) {
2     Thread({ f() }).start()
3 }

 

这个函数产生一个线程,它执行Runnable运行作为自变量接受的函数。RunnableJava中有单一方法的类,在Kotlin中由Lambda表达式替代。

 

 

现在,在我们的代码中,产生异步代码块:

1 doAsync { 
2     op1()
3     op2()
4     op3()
5 }

 

这样在{}内的每件事都将在第二个线程中执行。

 

 

内嵌函数

 

作为自变量接收的函数令人讨厌的是编译器需要为它们创建类,这将影响性能。但是,这可以用保留字inline容易地解决。

 

 

由于Inline函数是在编译时将它的代码替换对它的调用,所以在性能方面影响较少。为此,它不需要用额为的对象。

 

 

我们能够转换doAsync到一个inline函数:

1 inline fun doAsync(crossinline f: () -> Unit) {
2     Thread({ f() }).start()
3 }

 

在这个例子中,由于我们从另一个执行内容(另一个Lambda表达式)中调用f(),所以要求crossinline。不用太担心这些,在需要使用它时,编译器会提醒你的。

 

 

结论

 

如你所见,使用Lambda表达式后,我们能够简化很多我们的代码,甚至是在Java中不能实现的事。

 

 

另外,Kotlin的特别命名规则使我们能够创建属于我们自己的“开发语言”,并且还可以根据需要创建有意义的代码块。

 

 

Lambda表达式功能非常强大,这本书包含许多你能使用它们不同的情况。

 

KotlinJava interop

Kotlin的Lambda表达式以及它们怎样简化Android开发(KAD 07)