【问题标题】:Why doesn't filter method do a smart-cast on the object in the subsequent method in Kotlin为什么过滤方法不对Kotlin后续方法中的对象进行智能转换
【发布时间】:2020-07-06 06:34:48
【问题描述】:

这只是我写的一个示例代码。下面是 Comment 对象的数据类。

data class Comment(
    val id: Int,
    val text: String?
)

我正在对 Comment 对象列表执行过滤操作。

commentList.filter { comment -> comment.text != null }
    .map { comment -> comment.text.length }

这会导致在声明Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver 的comment.text 上出现编译器错误。所以我的问题是为什么过滤器方法不对文本对象进行智能转换并将其转换为不可为空的字符串类型?

还有没有更好的方法可以实现智能投射?

附言我知道我总是可以做到这一点,但出于好奇想知道是否有一些默认的 Kotlin 扩展功能可以完成这项工作。

commentList.filter { comment -> comment.text != null }
    .map { comment -> comment.text?.let { text ->
             text.length
        }
    }

【问题讨论】:

    标签: android kotlin


    【解决方案1】:

    首先,

    ...?.let { text ->
             text.length
        }
    

    可以简化为

    ...?.length
    

    我会进一步结合 filtermap 使用 mapNotNull:

    commentList.mapNotNull { comment -> comment.text?.length }
    

    如果length 在非null 输入上可能是null,它可能与您的原始代码有不同的结果,但它不能。

    【讨论】:

    【解决方案2】:

    这是因为智能转换在方法边界内工作。 filter()map() 是两种不同的方法。

    查看此answer 以获得更好的理解

    【讨论】:

      【解决方案3】:

      根据我在这里得到的评论和答案,我可以理解智能转换仅在方法边界内起作用。

      另外,我能够找到一个不同的解决方案,这使得代码在我看来有点优雅。

          commentList.mapNotNull { comment -> comment.text }
              .map { text -> text.length }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-03
        • 2020-01-10
        • 1970-01-01
        • 1970-01-01
        • 2021-07-30
        • 2021-10-10
        • 2013-09-04
        • 2020-11-27
        相关资源
        最近更新 更多