鉴于从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
的文档似乎非常相似。
这两个功能有什么区别?
答案 0 :(得分:17)
在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
作为别名保留,因为对于那些不熟悉这些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泛型方法实现 - 是否有一些原因?)