我可以直接将 MutableStateFlow 对象传递给 StateFlow 变量吗?

Hel*_*oCW 3 kotlin android-jetpack-compose

代码A来自此处的官方示例代码。

我觉得可以直接传_uiState过去uiState,所以就写了Code B,看来Code B可以很好的工作。

我可以直接将MutableStateFlow对象传递给变量吗?StateFlow

代码A

class InterestsViewModel(
    private val interestsRepository: InterestsRepository
) : ViewModel() {

    // UI state exposed to the UI
    private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
    val uiState: StateFlow<InterestsUiState> = _uiState.asStateFlow()

    ...
}
Run Code Online (Sandbox Code Playgroud)

代码B

class InterestsViewModel(
    private val interestsRepository: InterestsRepository
) : ViewModel() {

    // UI state exposed to the UI
    private val _uiState = MutableStateFlow(InterestsUiState(loading = true))
    val uiState: StateFlow<InterestsUiState> = _uiState

    ...
}
Run Code Online (Sandbox Code Playgroud)

Ten*_*r04 5

是的,这很好。有一个小的功能优势asStateFlow()。它不仅简单地向上转换为只读 StateFlow,而且还将其包装在只读 StateFlow 中,这样接收者就无法将其转换为 MutableStateFlow 并使用其发布功能。然而,这应该被认为是任何合理的代码都不应该做的事情,因为强行改变声明为只读的东西会带来麻烦。

没有对应的asList()功能MutableList(),所以我不确定为什么他们认为 Flows 需要此功能而 Collections 不需要。我找不到任何关于它的讨论。它出现在首次引入 StateFlow 和 SharedFlow 的同一提交中。

它的第二个特点asStateFlow()是它允许更简洁地编写此类代码。

val uiState = _uiState.asStateFlow()
Run Code Online (Sandbox Code Playgroud)

比写起来更容易和更快

val uiState: StateFlow<InterestsUiState> = _uiState
Run Code Online (Sandbox Code Playgroud)

或者

val uiState = _uiState as StateFlow<InterestsUiState>
Run Code Online (Sandbox Code Playgroud)

特别是当类型很长或很复杂时,例如StateFlow<List<SomeApi.Subtype>>