0

有一个数组:我在下面的代码中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. 可以看到备The condition 'it != null' is always true选项1&2中有检查说明,检查是否正确?因为我想确保只有非空项目notes可以放入payloadJson.
  2. 在备选方案 3 中,您可以看到有一个 Safe Call in filterNotNull()?.,这里是否?需要 ?,因为我查看了源代码,结果filterNotNull()不能为空,但是当我在其中删除?时,编译失败。
4

3 回答 3

2

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

notes: Array<KeyValueNote>? // Can be null, cannot contain nulls.
notes: Array<KeyValueNote?> // Cannot be null, can contain nulls.

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

于 2016-11-27T08:34:38.870 回答
1

notesis的类型Array<KeyValueNote>?,表示数组的元素不能为 null,但数组本身可以。因此,您在“我想要”部分的代码是正确的。一个较短的替代方案是:

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

关于您的替代方案:

  • 备选方案 1:永远不要let这样使用。它应该是一个安全的调用?.(就像在备选方案 2 中一样),仅此而已。当我看到let这些情况时,我的心在流血:(

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

  • 备选方案 3:由于数组的元素不能为空(因为它们的类型),filterNotNull所以相当于toList因为它只是复制了内容

于 2016-11-27T08:37:06.633 回答
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) }
于 2016-11-27T08:39:55.497 回答