Kotlin 中使用数组的安全调用令人困惑
Safe Calls in Kotlin with Array is confuse
有一个数组: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) }
我的问题
- 可以看到Alternative 1&2里面有Inspection Note
The condition 'it != null' is always true
,检查对不对?因为我只想保证里面的非空项notes
可以放在 payloadJson
.
- 备选方案3中,可以看到
filterNotNull()?.
里面有Safe Call,这里是否需要?
?,因为我复习了源代码,filterNotNull()
的结果不能为null,但是当我在那里删除?
时,编译失败。
检查是对的。您将 notes 变量声明为不可空项的可空数组。
notes: Array<KeyValueNote>? // Can be null, cannot contain nulls.
notes: Array<KeyValueNote?> // Cannot be null, can contain nulls.
考虑到这一点,filterNotNull()?. 对于此数组是必需的,因为它可以为空。您可以在 Kotlin documentation.
中找到有关 Kotlin 空安全的更多信息
notes
的类型是Array<KeyValueNote>?
,也就是说数组的元素不能为null,但是数组本身可以。因此,您在 "I want" 部分中的代码是正确的。一个较短的替代方案是:
notes?.forEach { payloadJson.put(it.key, it.value) }
关于您的备选方案:
备选方案 1:永远不要这样使用 let
。它应该是一个安全的调用 ?.
(就像在备选方案 2 中一样),没有别的。在那种情况下,当我看到 let
时,我的心在流血:(
备选方案2:takeWhile
和filter
显然不是一回事。我猜你想要 filterNotNull
,就像替代方案 3
备选方案 3:由于数组的元素不能为空(因为它们的类型),filterNotNull
等同于 toList
,因为它只是复制内容
我猜您对在不同范围内使用的 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
,其中 returns 源集合删除了 null
值。但是,如前所述,Array<KeyValueNote>
中不能有 null
值,因此不需要 filterNotNull
。
总之表达式可以写成:
notes?.forEach { payloadJson.put(it.key, it.value) }
有一个数组: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) }
我的问题
- 可以看到Alternative 1&2里面有Inspection Note
The condition 'it != null' is always true
,检查对不对?因为我只想保证里面的非空项notes
可以放在payloadJson
. - 备选方案3中,可以看到
filterNotNull()?.
里面有Safe Call,这里是否需要?
?,因为我复习了源代码,filterNotNull()
的结果不能为null,但是当我在那里删除?
时,编译失败。
检查是对的。您将 notes 变量声明为不可空项的可空数组。
notes: Array<KeyValueNote>? // Can be null, cannot contain nulls.
notes: Array<KeyValueNote?> // Cannot be null, can contain nulls.
考虑到这一点,filterNotNull()?. 对于此数组是必需的,因为它可以为空。您可以在 Kotlin documentation.
中找到有关 Kotlin 空安全的更多信息notes
的类型是Array<KeyValueNote>?
,也就是说数组的元素不能为null,但是数组本身可以。因此,您在 "I want" 部分中的代码是正确的。一个较短的替代方案是:
notes?.forEach { payloadJson.put(it.key, it.value) }
关于您的备选方案:
备选方案 1:永远不要这样使用
let
。它应该是一个安全的调用?.
(就像在备选方案 2 中一样),没有别的。在那种情况下,当我看到let
时,我的心在流血:(备选方案2:
takeWhile
和filter
显然不是一回事。我猜你想要filterNotNull
,就像替代方案 3备选方案 3:由于数组的元素不能为空(因为它们的类型),
filterNotNull
等同于toList
,因为它只是复制内容
我猜您对在不同范围内使用的 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
,其中 returns 源集合删除了 null
值。但是,如前所述,Array<KeyValueNote>
中不能有 null
值,因此不需要 filterNotNull
。
总之表达式可以写成:
notes?.forEach { payloadJson.put(it.key, it.value) }