【问题标题】:Kotlin filterNotNull for object propertiesKotlin filterNotNull 用于对象属性
【发布时间】:2018-03-06 15:47:16
【问题描述】:

我有以下(简化的)kotlin 代码:

data class Event(val name: String, val venue: Venue?)

data class Venue(val lat: Double, val lng: Double)

...

return events
        .filter { it.venue != null }
        .map { doSomething(it.venue.lat, it.venue.lng)

代码无法编译并出现错误Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type Venue?

我明白这意味着什么,但我不明白为什么编译器无法在.map 调用中找出it.venue 不能是null

如果事件可以为空,我可以写events.filterNotNull().name 或其他东西,编译器不会抱怨。有什么方法可以对可空对象属性而不是可空对象做同样的事情?

感谢您的宝贵时间

【问题讨论】:

    标签: compiler-errors kotlin nullable


    【解决方案1】:

    不,这是不可能的,无论是在当前版本的 Kotlin 中还是在当前正在考虑的任何潜在增强功能中。 Kotlin 编译器不够聪明,无法理解 filter 函数的语义,也无法知道在传递给该函数的 lambda 中执行的检查将影响不同 lambda 中的可能类型。

    (甚至不可能将“Event.venue 不为空的事件集合”的概念表达为 Kotlin 类型,更不用说推断map 的接收者将具有该类型。)

    【讨论】:

    • 感谢您的回答。那么filterNotNull 有什么特别之处吗?
    • 是的,filterNotNull 返回的类型与调用它的集合类型不同。
    • 啊哈,很有道理
    【解决方案2】:

    如果它会检查所有类似的情况,你的编译时间会超长。

    认为你可以做下一步:

    events
        .map { it.venue }
        .filterNotNull()
        .map { doSomething(it.lat, it.lng)
    

    【讨论】:

    • 编译器不仅仅是一个词法解析器。
    • 感谢您的回答。不幸的是,我无法映射到 Venue,因为“真实”代码在映射调用中使用了来自 Event 的多个属性
    • @yole 同意,我删除了那个
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多