博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
[译] Kotlin 揭秘:理解并速记 Lambda 语法
阅读量:5745 次
发布时间:2019-06-18

本文共 2596 字,大约阅读时间需要 8 分钟。

  • 原文地址:
  • 原文作者:
  • 译文出自:
  • 本文永久链接:
  • 译者:

在奥地利旅行期间,我参观了维也纳的奥地利国家图书馆。特别是国会大厅,这个令人惊叹的空间感觉就像印第安纳琼斯电影中的一些东西。房间周围的空间是这些门被装在架子上,很容易想象它们背后隐藏着什么样的秘密。

然而,事实证明,它们只是简单的图书馆。

让我们假设我们有一个应用程序来跟踪库中的书籍。有一天,我们想知道这个系列中最长和最短的书是什么。之后,我们编写代码,允许我们找到这两个:

val shortestBook = library.minBy { it.pageCount }val longestBook = library.maxBy { it.pageCount }复制代码

完美!但这让我感到疑惑,这些方法是如何工作的?it 是怎么知道的,只是写了 it.pageCount,到底该怎么做呢?

我做的第一件事就是定义 minBymaxBy,这两者都是在 。由于它们几乎完全相同,所以让我们来看看 maxBy,它从 1559 行开始。

那里的方法是在 [Iterable](https://developer.android.com/reference/java/lang/Iterable) 接口上构建的,但是如果我们做一个小的重写来使用[Collection](https://developer.android.com/reference/java/util/Collection)s,也许将一些变量的重命名变的更冗长,更容易理解:

public inline fun 
> Collection
.maxBy(selector: (T) -> R): T? { if (isEmpty()) return null var maxElement = first() var maxValue = selector(maxElement) for (element in this) { val value = selector(element) if (maxValue < value) { maxElement = element maxValue = value } } return maxElement}复制代码

我们可以看到它只是在 Collection 中获取每个元素,检查来自 selector 的值是否大于它看到的最大值。如果是,则保存元素和值。最后,它返回它找到的最大元素。相当简单。

然而 selector,看起来很整洁,它必须是允许我们在上面使用 it.pageCount 的东西,所以让我们再看看它。

即使只是在这一行中,甚至还有相当多的语法糖。在这种情况下,对于 selector: (T) -> R 来说是一个带有单个参数 T 的函数,并返回一些类型 R 相关的返回值。

可行的方法是 Kotlin 包含一组名为 FunctionN 的接口,其中 N 是它接受的参数数量。由于我们有一个参数,我们可以实现 Function1 接口,然后在我们的代码中使用它:

class BookSelector : Function1
{ override fun invoke(book: Book): Int { return book.pageCount }} val longestBook = library.maxBy(BookSelector())复制代码

这无疑显示了它的工作原理。selector 是一个 Function1,当给定 Book 时,返回一个 Int。然后,maxBy 获取 Int 并将其与它具有的值进行比较。

顺便说一句,这也解释了为什么泛型参数 R 具有类型 R [implements] Comparable <R>。如果 R 不是 Comparable,我们不能做 if(maxValue <value)

接下来的问题是,我们如何从那开始,到我们开始的一个循环?让我们逐步完成整个过程。

首先,代码可以替换为 lambda,它已经减少了很多:

val longestBook = library.maxBy({    it.pageCount})复制代码

下一步是如果方法的最后一个参数是 lambda,我们可以关闭括号,然后将 lambda 添加到行的末尾,如下所示:

val longestBook = library.maxBy() {    it.pageCount}复制代码

最后,如果一个方法只接受一个 lambda 参数,我们就可以完全放弃 () 方法,这会让我们回到初始代码:

val longestBook = library.maxBy { it.pageCount }复制代码

但是等等!那个 Function1 要怎么样!我每次使用它时都会执行分配吗?

这是一个很好的问题!好消息是,不,你不是。如果你再看一遍,你会看到它 maxBy 被标记为一个 inline 函数。这在编译期时会在源级别发生,因此虽然编译的代码比最初看起来的样本多,但是没有任何显着的性能影响,当然也没有对象分配。

真棒!现在,我们不仅知道图书馆中最短(也是最长)的书籍,我们还能更好地理解 maxBy 它是如何工作的。我们看到 Kotlin 如何使用[FunctionN](#full) lambda 的接口,以及如何将 lambda 表达式移到函数的参数列表之外。最后,我们知道,当只有一个 lambda 参数调用函数时,可以通常使用。

查看 博客,了解更多精彩内容,敬请期待更多关于 Kotlin 的文章!

如果发现译文存在错误或其他需要改进的地方,欢迎到 对译文进行修改并 PR,也可获得相应奖励积分。文章开头的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


是一个翻译优质互联网技术文章的社区,文章来源为 上的英文分享文章。内容覆盖 、、、、、、、等领域,想要查看更多优质译文请持续关注 、、。

转载地址:http://rjazx.baihongyu.com/

你可能感兴趣的文章
判断是否含有中文
查看>>
iOS开发UI篇—程序启动原理和UIApplication
查看>>
CAlayer(创建图层)
查看>>
android 学习随笔二十七(JNI:Java Native Interface,JAVA原生接口 )
查看>>
网站迁移至win2008r2系统II7.5以后,样式和图片都加载不了的问题
查看>>
vue.js框架组件中将JavaScript和HTML代码分离的两种方式
查看>>
自定义webkit浏览器滚动条样式
查看>>
System.currentTimeMillis()
查看>>
子网划分
查看>>
Byte[]、Image、Bitmap 之间的相互转换
查看>>
【线段树】【P4198】 楼房重建
查看>>
es6数组新方法
查看>>
leetcode:Factorial Trailing Zeroes
查看>>
【iOS开发】如何在程序出错崩溃时快速定位到具体出错代码行
查看>>
Elementary Methods in Number Theory Exercise 1.5.13
查看>>
文章评论:级数中达朗贝尔判别法和柯西判别法之间的关系研究 By 彭军
查看>>
陶哲轩实分析 命题 7.2.14 (极限算律) 证明
查看>>
Thread和Runnable
查看>>
JavaScript禁用页面内容选中和复制操作
查看>>
浅析Objective-C字面量
查看>>