gpt4 book ai didi

kotlin - 使用Kotlin契约在Iterable函数谓词中强制转换类型

转载 作者:行者123 更新时间:2023-12-02 13:07:39 24 4
gpt4 key购买 nike

我有这个密封的类PictureEvent:

sealed class PictureEvent {

data class PictureCreated(val pictureId: String, val url: String) : PictureEvent()

//more classes extending PictureEvent

}

现在,从 PictureEvent的列表中,我想获取第一个 PictureCreated:
fun doSomething(events: List<PictureEvent>) {

val creationEvent = events.first { isCreationEvent(it) } as PictureEvent.PictureCreated

//do stuff with the creationEvent

}

private fun isCreationEvent(event: PictureEvent) : Boolean {
return event is PictureEvent.PictureCreated
}

它工作正常。如您所见,由于 PictureCreated方法返回了 as,因此我将事件强制转换为 first(使用 PictureEvent关键字)。我想知道是否可以通过使用Kotlin契约(Contract)来避免这种转换。

我已经试过了:
private fun isCreationEvent(event: PictureEvent) : Boolean {
contract {
returns(true) implies (event is PictureEvent.PictureCreated)
}
return event is PictureEvent.PictureCreated
}

但这是行不通的。 first方法不断返回 PictureEvent而不是 PictureCreated。目前可以这样做吗?

最佳答案

该契约(Contract)可以正常工作,但是,如果您查看first方法签名,您应该能够了解正在发生的事情以及为什么未自动广播找到的对象的原因:

public inline fun <T> Iterable<T>.first(predicate: (T) -> Boolean): T
first方法的返回类型与为 Iterable实例中的所有元素定义的返回类型相同(在您的情况下为 PictureEvent),并且不幸的是,谓词内部没有自动广播可以更改此类型。

例如,可以使用所需的类类型来过滤列表,而不是使用契约(Contract),然后使用第一个元素:
val creationEvent = events
.filterIsInstance(PictureEvent.PictureCreated::class.java)
.first()

或创建类似于 first的扩展名:
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
val first = first { it is R }
return first as R
}

// or wrapping filterIsInstance
inline fun <reified R> Iterable<*>.firstOfInstance(): R {
return filterIsInstance(R::class.java).first()
}

val creationEvent = events.firstOfInstance<PictureEvent.PictureCreated>()

关于kotlin - 使用Kotlin契约在Iterable函数谓词中强制转换类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61639584/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com