繁体   English   中英

kotlin中密封接口的正确使用方法

[英]Proper way of using sealed interface in kotlin

我在 kotlin 的sealed Interface中是全新的。我正在尝试通过 android kotlin 中的sealed进行 state 管理。我的主要目标是when我使用sealed的 object 时,我不想继承所有孩子。 我不确定sealed interface对我来说是否是正确的选择。 我所有的代码可能都是错误的,如果我错了请指正谢谢。

sealed interface ConnectionUIState

sealed class BluetoothConnectionUIState {
    object Initial : BluetoothConnectionUIState()
    data class ScanningDevice(val storedDevice: SnapshotStateList<BluetoothDevice>? = null) : ConnectionUIState
}

我像这样初始化变量

var uiState by mutableStateOf<BluetoothConnectionUIState>(BluetoothConnectionUIState.Initial)
        private set

现在我在 function 中传递uiState变量并使用when语句

when (uiState) {
        BluetoothConnectionUIState.ScanningDevice -> {
            xuz()
        }
    }

为什么when语句出错

'when' expression must be exhaustive, add necessary 'Initial' branch or 'else' branch instead

此外,这一行也在when语句中给我错误BluetoothConnectionUIState.ScanningDevice

错误

Classifier 'ScanningDevice' does not have a companion object, and thus must be initialized here

如果我在这里做错了。 您能否详细说明此堆栈溢出的 2 点。 谢谢

更新

我做了一些改变

sealed interface ConnectionUIState

sealed class BluetoothConnectionUIState {
    object Initial : ConnectionUIState
    data class ScanningDevice(val storedDevice: SnapshotStateList<BluetoothDevice>? = null) : BluetoothConnectionUIState()
}

我在when声明它没有抱怨Initial时取得了成功

when (uiState) {
        is BluetoothConnectionUIState.ScanningDevice -> {
            BluetoothPairContent(viewModel, tryAgainAction, openSettingAction, scanDeviceList)
        }
    }

这是我的目标,但另一个问题是它在uiState初始化时间给出了错误

var uiState by mutableStateOf<BluetoothConnectionUIState>(BluetoothConnectionUIState.Initial)
        private set

错误

Type mismatch.
Required:
BluetoothConnectionUIState
Found:
BluetoothConnectionUIState.Initial

我又糊涂了。 请指导我。 谢谢

(我想你已经解决了,但以防万一 - 你需要is你的when检查某物is是 class。当与object比较时,你使用相等性,它可以写成要匹配的值)

处理您的更新:

// simplified for readability
sealed interface ConnectionUIState

sealed class BluetoothConnectionUIState {
    object Initial : ConnectionUIState
    data class ScanningDevice : BluetoothConnectionUIState()
}

您已将 object 和 class嵌套在BluetoothConnectionUIState中,这意味着它们的完全限定名称类似于BluetoothConnectionUIState.Initial 但你实际上不必嵌套它们,你可以这样做:

sealed class BluetoothConnectionUIState
object Initial : ConnectionUIState
data class ScanningDevice : BluetoothConnectionUIState()

现在InitialScanningDevice没有嵌套在BluetoothConnectionUIState中,您只需直接引用它们。 那么他们现在是什么关系呢? 查看构造函数:

// subclass of BluetoothConnectionUIState
data class ScanningDevice : BluetoothConnectionUIState()

// implements the ConnectionUIState interface
object Initial : ConnectionUIState

去掉嵌套后,可以看到Initial实际上和密封的 class 完全没有类型关系。 它恰好位于其中。 这就是为什么你不能把它放在你的mutableStateOf中——它不是 BluetoothConnectionUIState。

这也是为什么您在原始when块中收到must be exhaustive错误的原因 - 您只有一个分支检查Initial ,无论如何它都不是密封的 class 的一部分。 它在您检查ScanningDevice时起作用,因为它是 class 的唯一成员 - 如果uiStateBluetoothConnectionUIState ,则它必须是ScanningDevice


如何解决这个问题取决于您 - 似乎您希望这两件事成为同一个密封 class 的一部分。也许您希望ConnectionUIState成为密封的 class? 因为这就是他们俩所代表的。 并且BluetoothConnectionUIState是您可以选择性地应用于该密封 class 的某些成员的接口吗?

sealed interface BluetoothConnectionUIState

sealed class ConnectionUIState {
    object Initial : ConnectionUIState()
    data class ScanningDevice : ConnectionUIState(), BluetoothConnectionUIState
}

这个概述也可能是一个有用的阅读!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM