Kotlin 中的条件副作用和可选类型
Conditional side-effects and optional types in Kotlin
我正在尝试在 Kotlin 中执行一个简单的副作用:
fun handle(request: Request) {
repository.findByUID(request.userId)?.let {
if (someCondition) return
service.run(...)
}
}
如您所见,当 repository return 是一个非空值并且 someCondition 很满意。
是否有任何 Kotlin 方式来执行此操作而不是使用 if{}-return 构造?
在Java8中,可以通过以下方式实现:
optional
.filter(...)
.ifPresent(...)
更新:
Kotlin 1.1 有一个方法叫做 takeIf
:
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
你可以这样使用:
repository.findByUID(request.userId)?.takeIf { someCondition }?.let { service -> }
Kotlin 在标准库中不包含这样的方法。
但是,您可以定义它:
inline fun <K : Any> K.ifPresent(condition: K.() -> Boolean): K? = if (condition()) this else null
使用此方法,您的示例可以重写为:
fun handle(request: Request) {
repository.findByUID(request.userId)?.ifPresent { someCondition }?.let {
service.run(...)
}
}
另一种选择可能是使用列表的内置扩展(但使用列表会产生开销):
listOf(repository.findByUID(userId)).filter { someCondition }.forEach { service.run(...) }
Kotlin 的 nullable types are very similar to Java's Optional (which is very similar to Guava's Optional).
在 Kotlin 1.1 中你可以使用 takeIf
which "is like filter
for a single value" (takeIf() and also() - What's New in Kotlin 1.1 - Kotlin Programming Language):
repository.findByUID(request.userId).takeIf { !someCondition }?.let { service.run(...) }
Kotlin 1.0 没有为可空类型定义 map
、flatMap
、filter
/takeIf
等,但您可以轻松定义自己的函数。例如:
inline fun <T> filter(value: T?, predicate: (T) -> Boolean): T? {
return if (value != null && predicate(value)) value else null
}
用法示例:
filter(repository.findByUID(request.userId)) { !someCondition }?.let { service.run(...) }
我会在没有额外库或扩展函数的情况下使用此构造:
?.let { if (someCondition) null else it }
将此构造应用于原始问题的代码示例后,它看起来像:
fun handle(request: Request) {
repository.findByUID(request.userId)
?.let { if (someCondition) null else it }
?.let {
service.run {
/* ... */
}
}
}
或者至少它看起来不错,在定义 Request
、repository
、findByUid
等之后编译并在我的代码库中具有相同的类型。:-)
我正在尝试在 Kotlin 中执行一个简单的副作用:
fun handle(request: Request) {
repository.findByUID(request.userId)?.let {
if (someCondition) return
service.run(...)
}
}
如您所见,当 repository return 是一个非空值并且 someCondition 很满意。
是否有任何 Kotlin 方式来执行此操作而不是使用 if{}-return 构造?
在Java8中,可以通过以下方式实现:
optional
.filter(...)
.ifPresent(...)
更新:
Kotlin 1.1 有一个方法叫做 takeIf
:
/**
* Returns `this` value if it satisfies the given [predicate] or `null`, if it doesn't.
*/
@kotlin.internal.InlineOnly
@SinceKotlin("1.1")
public inline fun <T> T.takeIf(predicate: (T) -> Boolean): T? = if (predicate(this)) this else null
你可以这样使用:
repository.findByUID(request.userId)?.takeIf { someCondition }?.let { service -> }
Kotlin 在标准库中不包含这样的方法。
但是,您可以定义它:
inline fun <K : Any> K.ifPresent(condition: K.() -> Boolean): K? = if (condition()) this else null
使用此方法,您的示例可以重写为:
fun handle(request: Request) {
repository.findByUID(request.userId)?.ifPresent { someCondition }?.let {
service.run(...)
}
}
另一种选择可能是使用列表的内置扩展(但使用列表会产生开销):
listOf(repository.findByUID(userId)).filter { someCondition }.forEach { service.run(...) }
Kotlin 的 nullable types are very similar to Java's Optional (which is very similar to Guava's Optional).
在 Kotlin 1.1 中你可以使用 takeIf
which "is like filter
for a single value" (takeIf() and also() - What's New in Kotlin 1.1 - Kotlin Programming Language):
repository.findByUID(request.userId).takeIf { !someCondition }?.let { service.run(...) }
Kotlin 1.0 没有为可空类型定义 map
、flatMap
、filter
/takeIf
等,但您可以轻松定义自己的函数。例如:
inline fun <T> filter(value: T?, predicate: (T) -> Boolean): T? {
return if (value != null && predicate(value)) value else null
}
用法示例:
filter(repository.findByUID(request.userId)) { !someCondition }?.let { service.run(...) }
我会在没有额外库或扩展函数的情况下使用此构造:
?.let { if (someCondition) null else it }
将此构造应用于原始问题的代码示例后,它看起来像:
fun handle(request: Request) {
repository.findByUID(request.userId)
?.let { if (someCondition) null else it }
?.let {
service.run {
/* ... */
}
}
}
或者至少它看起来不错,在定义 Request
、repository
、findByUid
等之后编译并在我的代码库中具有相同的类型。:-)