在kotlin中写入可分配的值
后端返回可空Int? 我应该如何编写可以为空的值?
date class Foo (var value: Int?){ constructor(source: Parcel) : this( source.readInt() ) override fun writeToParcel(dest: Parcel, flags: Int) { dest.writeInt(value) // doesn't compile - writeInt expect no null value } }
现在我解决了:
dest.writeInt(value?: -1)
然后检查到-1
或者像Int字符串写入Int然后使用…的值…
但我认为这是丑陋的错误。
解决! 我的答案:
source.readValue(Int::class.java.classLoader) as Int?, dest.writeValue(value)
解决方案:
source.readValue(Int::class.java.classLoader) as Int?, dest.writeValue(value)
这在很大程度上取决于null
作为可空属性的值的语义。 这可能意味着:
-
如果
value
为零,那么它是缺席的,不应该写:value?.let { writeInt(it) }
当然,
Parcel
接收者应该能够确定是否应该读取值,这应该从前面写的值中清楚。 -
value
是由一些代码提供的,如果它应该被写入的地方是空的,那么它是一个错误:check(value != null) { "value should be not null at the point it's wriiten" } writeInt(value!!)
此外,在这种情况下,请考虑使用
lateinit var
而不是可以为空的属性。 -
应该使用一些默认值而不是
value
:writeInt(value ?: someDefaultValue())
使用
Parcel
,这是有道理的,否则,如果缺少值,则必须在其他地方指定事实。 -
…(
null
实际上可能意味着很多东西)
此外, 这个答案显示了处理可空值的许多惯用方法,你可能会发现其中的一些有用的。
考虑一下Google Play服务用来安全地编组空字符串:
String NULL = "SAFE_PARCELABLE_NULL_STRING";
这在技术上不是一个空字符串,团队决定在语义上这个字符串等于空。
处理列表时我们使用类似的技术。 首先我们writeInt
列表的长度。 这可能是-1
来表示列表为空。
是否可以使用-1
来表示不存在整数取决于您的模式。 在你的用例中是-1
是一个有效的值? 如果是这样,你必须find另一个值来表示你的null,如Int.MIN
或Int.MAX
。
如果所有这些值都在有效范围内,请使用另一个值,如下所示:
val hasValue: Boolean = value != null val hasValueByte: Byte = if (value != null) 1 else 0 dest.writeByte(hasValueByte) if (hasValue) dest.writeInt(value)
不要忘记在解组的情况下!
val parcelHasValueByte = source.readByte() val parcelHasValue = parcelHasValueByte != 0 if (parcelHasValue) { value = source.readInt() } else { value = null }