Kotlin,目标 Java 互操作:惰性集合的惯用类型?
Kotlin, targeting Java interop: Idiomatic type for lazy collection?
当以 Java 互操作为目标时,惰性集合应该使用哪种类型?
Sequence<T>
对 Kotlin 调用者最有意义,因为它的扩展函数默认是惰性的,但强制 Java 调用者处理 Kotlin stdlib 类型并手动转换序列迭代器(序列不扩展可迭代!)
由于 for 循环中的隐式使用,Iterable<T>
对 Java 调用者有意义,但会导致毫无戒心的 Kotlin 调用者因非惰性扩展函数而意外放弃惰性
Stream<T>
对于 Java 和 Kotlin 调用者都是最佳的,但可能有开销并且是 Java 8+(Kotlin 目标 6+)
你可以通过同时实施这三项来让每个人都开心。例如:
data class User(val name: String)
fun userSequence(): Sequence<User> = TODO()
fun usersLazily(): Iterable<User> = userSequence().asIterable()
fun userStream(): Stream<User> = userSequence().asStream()
通过不为这些函数中的任何一个使用像 users
这样的简单名称,您可以让调用者多考虑一下他们真正想要的函数:
- Kotlin 用户将使用
userSequence
。
- Java 1.6 和 1.7 用户将使用
usersLazily
。
- Java 1.8用户将使用
userStream
.
userStream
必须在单独的 JAR 中定义,添加 JDK 1.8 支持到您的 1.6/1.7 JAR(类似于 org.jetbrains.kotlin:kotlin-stdlib-jre8
对 org.jetbrains.kotlin:kotlin-stdlib
的支持) .
话虽如此,我会质疑您是否真的需要维护 Java 1.6 或 1.7 支持。如果您发现没有,那么您可以将 userSequence
和 userStream
放入同一个 JAR 中,甚至不定义 usersLazily
.
当以 Java 互操作为目标时,惰性集合应该使用哪种类型?
Sequence<T>
对 Kotlin 调用者最有意义,因为它的扩展函数默认是惰性的,但强制 Java 调用者处理 Kotlin stdlib 类型并手动转换序列迭代器(序列不扩展可迭代!)
由于 for 循环中的隐式使用,Iterable<T>
对 Java 调用者有意义,但会导致毫无戒心的 Kotlin 调用者因非惰性扩展函数而意外放弃惰性Stream<T>
对于 Java 和 Kotlin 调用者都是最佳的,但可能有开销并且是 Java 8+(Kotlin 目标 6+)
你可以通过同时实施这三项来让每个人都开心。例如:
data class User(val name: String)
fun userSequence(): Sequence<User> = TODO()
fun usersLazily(): Iterable<User> = userSequence().asIterable()
fun userStream(): Stream<User> = userSequence().asStream()
通过不为这些函数中的任何一个使用像 users
这样的简单名称,您可以让调用者多考虑一下他们真正想要的函数:
- Kotlin 用户将使用
userSequence
。 - Java 1.6 和 1.7 用户将使用
usersLazily
。 - Java 1.8用户将使用
userStream
.
userStream
必须在单独的 JAR 中定义,添加 JDK 1.8 支持到您的 1.6/1.7 JAR(类似于 org.jetbrains.kotlin:kotlin-stdlib-jre8
对 org.jetbrains.kotlin:kotlin-stdlib
的支持) .
话虽如此,我会质疑您是否真的需要维护 Java 1.6 或 1.7 支持。如果您发现没有,那么您可以将 userSequence
和 userStream
放入同一个 JAR 中,甚至不定义 usersLazily
.