使用Array在Kotlin中进行安全调用会让人感到困惑

时间:2016-11-27 06:43:57

标签: arrays kotlin kotlin-android-extensions

有一个数组:notes: Array<KeyValueNote>?我在下面的代码中使用了Kotlin 1.0.5-2

我想要

if (notes != null) {
    for (note in notes) {
        // Put the note to the payload Json object only if the note is non-null.
        payloadJson.put(note.key, note.value)
    }
}

但是有几个变化

    // Alternative 1.
    notes?.let {
        it.takeWhile { it != null /** Inspection will note The condition 'it != null' is always true' in here**/ }.forEach { payloadJson.put(it.key, it.value) }
    }

    // Alternative 2.
    notes?.takeWhile { it != null /** Inspection will note The condition 'it != null' is always true' in here**/ }?.forEach { payloadJson.put(it.key, it.value) }

    // Alternative 3.
    notes?.filterNotNull()?.forEach { payloadJson.put(it.key, it.value) }

我的问题

  1. 您可以在备选方案1&amp; 2中​​看到备注The condition 'it != null' is always true检查是否正确?因为我想确保{{}中只有非空项目1}}可以放到notes
  2. 在备选方案3中,您可以在payloadJson中看到安全通话,此处是否需要filterNotNull()?.,因为我查看了源代码, ?的结果不能为空,但当我删除filterNotNull()时,编译失败。

3 个答案:

答案 0 :(得分:2)

检查是对的。您将notes变量声明为可空项目的可空数组。

wreq

考虑到这一点,此数组需要 filterNotNull()?。,因为它可以为空。您可以在Kotlin documentation中找到有关Kotlin null安全性的更多信息。

答案 1 :(得分:1)

notes的类型是Array<KeyValueNote>?,这意味着数组的元素不能为空,但数组本身可以。因此,你的代码在&#34;我想要&#34;部分是正确的。一个较短的替代方案是:

notes?.forEach { payloadJson.put(it.key, it.value) }

关于您的替代方案:

  • 备选方案1:绝不要像这样使用let。这应该是一个安全的电话?.(如备选方案2中所示),没有别的。当我在这些情况下看到let时,我的心会流血:(

  • 备选方案2:takeWhilefilter显然不是一回事。我想你想要filterNotNull,就像在备选方案3

  • 中一样
  • 备选3:由于数组的元素不能为空(因为它们的类型),filterNotNull等同于toList,因为它只是复制内容

    < / LI>

答案 2 :(得分:1)

我猜你对不同范围内使用的it参数感到困惑。第一种选择可以改写为:

notes?.let { notesSafe:Array<KeyValueNote> -> // notesSafe is not null here
    notesSafe
      .takeWhile { item:KeyValueNote -> item != null } // item is already not null by it's type definition
      .forEach { payloadJson.put(it.key, it.value) }
}

第二种选择几乎相同,编译器关于item:KeyValueNote的注释也是正确的,原因相同:val items:Array<KeyValueNote>?无法保存null值 - 但items本身可能是null

第三种方法可以安全地调用filterNotNull,它会返回已删除null值的源集合。但是,如上所述Array<KeyValueNote>中不能包含null值,因此不需要filterNotNull

总之,表达式可以写成:

notes?.forEach { payloadJson.put(it.key, it.value) }