【问题标题】:Kotlin incorrectly inferring type nullability while using RxJava2Kotlin 在使用 RxJava2 时错误地推断类型可空性
【发布时间】:2018-05-28 10:15:40
【问题描述】:

我在尝试编写一段负责发现蓝牙设备的代码时遇到了一个非常令人沮丧的问题。

根据Android Studio,这段代码是正确的:

fun discoverDevices(): Observable<BluetoothDevice> {
    val discovered: HashSet<BluetoothDevice> = HashSet()
    return bluetoothUtil.startDiscovery()
            .flatMapObservable { discoveryStarted ->
                if(discoveryStarted) {
                    RxBroadcastReceiver.create(appContext, IntentFilter().apply {
                        addAction(BluetoothDevice.ACTION_FOUND)
                        addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
                    })
                } else {
                    Observable.error(Throwable("Discovery couldn't be started"))
                }
            }
            .takeUntil { intent ->
                intent.action == BluetoothAdapter.ACTION_DISCOVERY_FINISHED
            }
            .map { intent ->
                var bluetoothDevice: BluetoothDevice? = null
                if(intent.action == BluetoothDevice.ACTION_FOUND) {
                    bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                }
                if(bluetoothDevice != null && !discovered.contains(bluetoothDevice))
                    bluetoothDevice
                else
                    null
            }
}

该函数声明它返回Observable&lt;BluetoothDevice&gt;,尽管很明显map 函数将返回BluetoothDevice?。此外,我尝试通过附加来强制它过滤空值

.filter {
    it != null
}

到链的末尾,条件it != null 突出显示为“始终为真”,返回值突然变为Observable&lt;BluetoothDevice?&gt;。这非常令人沮丧,我似乎无法找到解决这个奇怪问题的方法。

这是 Android Studio 的错误还是我做错了什么?

【问题讨论】:

  • 很抱歉没有提供直接的答案,但是如果你使用 Kotlin Coroutines,这种分散在几个高阶函数中的凌乱逻辑将成为一个超级干净和明显的循环。
  • 仍处于实验阶段,因此我不允许在我公司的生产代码中使用它。
  • 他们有“实验性”的绰号,但他们也有 JetBrains 的 100% 承诺,即使在发布后也支持实验性 API。 JetBrains 还指出,它们已完全准备好生产,但仍保留在最终版本中更改 API 的权利。

标签: android kotlin rx-java2


【解决方案1】:

这有一个非常简单的解释:null 值在 RxJava2 中支持。

使用null 将在运行时抛出NullPointerException,如下所述:What's different in 2.0

在您的特定情况下,IDE 将表达式突出显示为“始终为真”,因为 RxJava2 运算符不支持可为空的类型,因此它永远不会发出一个。

【讨论】:

  • 嗯,这很明显不是吗。非常感谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多