3

Im investigating Kotlin MutableStateFlow/StateFlow and would like to declare my MutableStateFlow in a Generic Base Class as follows:-

class MyBaseClass<S> {

private val internalState = MutableStateFlow<S>(//WHAT GOES HERE????//)

    val state: StateFlow<S>
        get() = internalState

}

The issue I am stuck with is that MutableStateFlow has a mandatory initial value.

I cannot see how to provide a generic initial value of Type "S"

Is it possible to use this approach of employing a generic base class instance variable?

Hector
  • 4,016
  • 21
  • 112
  • 211
  • 1
    I found this question useful https://stackoverflow.com/questions/43477903/instantiating-a-generic-type-in-kotlin – Steyrix Sep 01 '20 at 08:52
  • Anyways, I think you can wrap S with something, that you can instantiate via known constructor/provider. Maybe some wrapper class? – Steyrix Sep 01 '20 at 08:54
  • @Steyrix thanks for the suggestion, I had already see that question/answer, however I do not like the idea of using .class constructors etc – Hector Sep 01 '20 at 08:57
  • 1
    Can't you just add a parameter to the constructor of `MyBaseClass` indicating the default value, and then just pass that to `MutableStateFlow()`? – Lino Sep 01 '20 at 09:08

2 Answers2

3

Building up on Harshith Shetty answer all I did differently was to initialize the internalState as lazy so I can avoid the accessing non-final property in constructor warning

abstract class MyBaseClass<S> {

    abstract val initialState: S

    private val internalState: MutableStateFlow<S> by lazy { MutableStateFlow(initialState) }

    val state: StateFlow<S>
        get() = internalState

}

Btw there is no way to inizialize MutableStateFlow without initial value. If you absolutely do not want an initial value use ConflatedBroadcastChannel instead.

e.g.

val internalState: ConflatedBroadcastChannel<S> = ConflatedBroadcastChannel()

ThanosFisherman
  • 5,626
  • 12
  • 38
  • 63
1

You can take the default initial state value from derived class like,

abstract class MyBaseClass<S> {

    abstract val initialState: S

    private val internalState = MutableStateFlow<S>(initialState)

    val state: StateFlow<S>
        get() = internalState

}
Harshith Shetty
  • 351
  • 4
  • 10