Home > Back-end >  Can I pass a MutableStateFlow object to a StateFlow variable directly?
Can I pass a MutableStateFlow object to a StateFlow variable directly?

Time:10-26

The Code A is from offical sample code here.

I think I can pass _uiState to uiState directly, so I write Code B, it seems that Code B can work well.

Can I pass a MutableStateFlow object to a StateFlow variable directly?

Code 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()

    ...
}

Code 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

    ...
}

CodePudding user response:

Yes, this is fine. There is one small functional advantage to asStateFlow(). It does not simply upcast to a read-only StateFlow, but also wraps it in a read-only StateFlow, such that a receiver cannot cast it to a MutableStateFlow and use its publishing functions. However, this should be considered something that no reasonable code should ever do, because it is asking for trouble to forcibly mutate something that is declared as read-only.

There is no equivalent asList() for MutableList(), so I'm not sure why they felt Flows need this feature and Collections don't. I can't find any discussion of it. It appeared in the same commit that first introduced StateFlow and SharedFlow.

A secondary feature of asStateFlow() is that it permits writing this kind of code more concisely.

val uiState = _uiState.asStateFlow()

is easier and faster to write than

val uiState: StateFlow<InterestsUiState> = _uiState

or

val uiState = _uiState as StateFlow<InterestsUiState>

especially if the type is long or complicated, such as StateFlow<List<SomeApi.Subtype>>, for example.

  • Related