![](/img/trans.png)
[英]Firestore (Kotlin) proper way to convert a complete task into a sealed class when performing a document request
[英]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()
现在Initial
和ScanningDevice
没有嵌套在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 的唯一成员 - 如果uiState
是BluetoothConnectionUIState
,则它必须是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.