find和firstOrNull有什么区别?
鉴于从Kotlin Koans提取的以下代码:
fun Shop.findAnyCustomerFrom(city: City): Customer? { // Return a customer who lives in the given city, or null if there is none return customers.firstOrNull { it.isFrom(city) } }
我自己的解决方案使用customers.find
。 两者都在公案情况下工作。
firstOrNull
和find
的文档似乎非常相似。
这两个功能有什么区别?
在2014年的这个主题中,Kotlin社区成员和JetBrains工作人员讨论了不同方法find
和firstOrNull
:
https://youtrack.jetbrains.com/issue/KT-5185
JetBrains的员工Ilya Ryzhenkov表示:
我认为我们可以不赞成
find
并使其成为firstOrNull
的别名。 就像indexOf
具有众所周知的语义一样,find
也被广泛认为是“查找第一个项匹配谓词,如果没有找到则返回null”。 喜欢精确含义的人可以用firstOrNull
,singleOrNull
来表达意图。
换一种说法:
-
find(predicate)
和firstOrNull(predicate)
在行为上是相同的,find
可以被认为是firstOrNull
别名 -
find
被find
是一个别名,因为对于那些还不熟悉这些Linq风格或功能方法的程序员来说,它更直观,更容易被发现。
实际上, Array<out T>.find
的定义没有被定义为别名,而是作为一个包装器(尽管优化编译器将内联它,有效地使其成为一个别名):
https://github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Arrays.kt#L657
@kotlin.internal.InlineOnly public inline fun <T> Array<out T>.find(predicate: (T) -> Boolean): T? { return firstOrNull(predicate) }
同上Sequence<T>.find
:
https://github.com/JetBrains/kotlin/blob/1.1.3/libraries/stdlib/src/generated/_Sequences.kt#L74
@kotlin.internal.InlineOnly public inline fun <T> Sequence<T>.find(predicate: (T) -> Boolean): T? { return firstOrNull(predicate) }
(我自己并不是一个Kotlin用户,但我很惊讶这些方法是作为编译时生成的代码实现的,而不是作为单个JVM泛型方法手动定义的 – 是否有一些原因呢?