类型不匹配:推断类型是 BluetoothDevice?但 BluetoothDevice 是预期的

Type mismatch: inferred type is BluetoothDevice? but BluetoothDevice was expected

我知道这是一个非常简单的错误,但我还不能完全理解 kotlin 的细微差别来解决它。

我遇到错误:

Type mismatch: inferred type is BluetoothDevice? but BluetoothDevice was expected

尝试将 BluetoothDevice 作为 parcelable

传递时
class ScanDevice(var device: BluetoothDevice, var rssi: Int): Parcelable {
   ...
    constructor(parcel: Parcel) : this(
        parcel.readParcelable(BluetoothDevice::class.java.classLoader), <--- here
        parcel.readInt()
    )
    ...

从技术上讲,这只是一个警告,实际上并不是错误,但我不确定这里发生了什么。

这是因为 Parcel.readParcelable 可以为空。如果 Parcel 之前在该位置写入了空值,则返回空值。在您的情况下,如果您可以保证永远不会将 null 写入 Parcel,您可以简单地断言该值不为 null:

constructor(parcel: Parcel) : this(
    parcel.readParcelable(BluetoothDevice::class.java.classLoader)!!,
    parcel.readInt()
)

如果将空值写入 Parcel,这将在运行时崩溃。

documentation for Parcel.readerParcelable() 说:

Returns the newly created Parcelable, or null if a null object has been written.

这意味着,如果我们生活在 Kotlin 世界中,Parcel.readParcelable() 的 return 类型将是 T? 而不是 T (即它可以为空).

由于您可以控制写作,因此您知道它不会return为空。这意味着您可以安全地使用 !! 运算符将结果转换为不可为 null 的类型:

parcel.readParcelable(BluetoothDevice::class.java.classLoader)!!

而不是使用!!像这样执行空安全调用可能会更好。

parcel?.let{
    it.readParcelable(BluetoothDevice::class.java.classLoader) 
    it.readInt()
}

这仅在parcel 不为空时执行代码。仅当您 100% 确定 variable/object 不为空时才使用 !!