在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.MINInt.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 }