映射选项时 RxKotlin 出现意外的空指针异常
Unexpected NullPointException with RxKotlin when mapping optionals
首先,我有以下 Moshi json。
@JsonClass(generateAdapter = true)
data class OrderDetails(
@Json(name = "_id") val id: Int,
@Json(name = "status") val status: String,
@Json(name = "tableNo") val tableNo: Int,
@Json(name = "serverId") val serverId: Int?,
@Json(name = "items") val orderItems: List<OrderDetailsItem>
)
所有这些字段都应该有除 serverId 之外的数据。
此数据是从服务器中获取的,我可以在其中允许用户 select 订购。
onSeletedOrder
.map { it.orderDetails.serverId } //blows up here apparently.
.filterNotNull() //have tried this but it doesn't matter.
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
当我映射到上面的 serverId 时,我遇到了 NPE。
有趣的是地图(即使它是可选的)之后进行了不安全的转换。
我希望它在地图之后保持可选性。
我假设这是因为向后桥接到 RxJava。
想知道是否有人对这是为什么有进一步的解释。
RxJava 不允许流中有空值。理想情况下,您应该在项目进入流之前执行此过滤器,但如果您不能这样做,您可以采用的一种解决方法是使用空字符串代替 null。
onSeletedOrder
.map { it.orderDetails.serverId.orEmpty() }
.filter { it.isNotEmpty() }
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
对于“map
,但不包括某些元素”,RxJava有flatMapMaybe
(除Observable
之外的其他类型也可以有对应的return类型):
// helper
fun <T> T?.toMaybe(): Maybe<T> = if (this != null) Maybe.just(this) else Maybe.empty<T>
onSeletedOrder
.flatMapMaybe { it.orderDetails.serverId.toMaybe() }
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
最好的方法是使用可选数据格式化数据 Class。
@JsonClass(generateAdapter = true)
data class OrderDetails(
@Json(name = "_id") val id: Int? = 0,
@Json(name = "status") val status: String? = "Not active",
@Json(name = "tableNo") val tableNo: Int? = 0,
@Json(name = "serverId") val serverId: Int? = 0,
@Json(name = "items") val orderItems: List<OrderDetailsItem>? = listOf()
)
您不会收到任何 NPE
首先,我有以下 Moshi json。
@JsonClass(generateAdapter = true)
data class OrderDetails(
@Json(name = "_id") val id: Int,
@Json(name = "status") val status: String,
@Json(name = "tableNo") val tableNo: Int,
@Json(name = "serverId") val serverId: Int?,
@Json(name = "items") val orderItems: List<OrderDetailsItem>
)
所有这些字段都应该有除 serverId 之外的数据。 此数据是从服务器中获取的,我可以在其中允许用户 select 订购。
onSeletedOrder
.map { it.orderDetails.serverId } //blows up here apparently.
.filterNotNull() //have tried this but it doesn't matter.
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
当我映射到上面的 serverId 时,我遇到了 NPE。 有趣的是地图(即使它是可选的)之后进行了不安全的转换。 我希望它在地图之后保持可选性。 我假设这是因为向后桥接到 RxJava。 想知道是否有人对这是为什么有进一步的解释。
RxJava 不允许流中有空值。理想情况下,您应该在项目进入流之前执行此过滤器,但如果您不能这样做,您可以采用的一种解决方法是使用空字符串代替 null。
onSeletedOrder
.map { it.orderDetails.serverId.orEmpty() }
.filter { it.isNotEmpty() }
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
对于“map
,但不包括某些元素”,RxJava有flatMapMaybe
(除Observable
之外的其他类型也可以有对应的return类型):
// helper
fun <T> T?.toMaybe(): Maybe<T> = if (this != null) Maybe.just(this) else Maybe.empty<T>
onSeletedOrder
.flatMapMaybe { it.orderDetails.serverId.toMaybe() }
.flatMap { findServerBy(it) }
.map { "${it.firstname} ${it.lastname}" }
最好的方法是使用可选数据格式化数据 Class。
@JsonClass(generateAdapter = true)
data class OrderDetails(
@Json(name = "_id") val id: Int? = 0,
@Json(name = "status") val status: String? = "Not active",
@Json(name = "tableNo") val tableNo: Int? = 0,
@Json(name = "serverId") val serverId: Int? = 0,
@Json(name = "items") val orderItems: List<OrderDetailsItem>? = listOf()
)
您不会收到任何 NPE