Skaldebane
08/11/2024, 10:29 PMclass ViewModel {
val count: StateFlow<Int>
field = MutableStateFlow(0)
}
And this looks very nice and all... but has a big drawback, which is that relying on just the type conversion to a superclass is not enough to enforce what we really want here.
I can very easily do this:
(viewModel.count as MutableStateFlow<Int>).value = 1
And this code would work just fine, which is not great.
Same thing applies to stuff like MutableList
-> List
.
The usual approach is to use asStateFlow()
here, which would actually prevent modifications through type casting, because it converts the underlying type to ReadonlyStateFlow
, which can't be modified.
I don't know if this is already planned, but it would be great if we can provide custom initializers like this:
class ViewModel {
val count: StateFlow<Int> = field.asStateFlow()
field = MutableStateFlow(0)
}
where we can use the field
in the initializer.Skaldebane
08/11/2024, 10:33 PMclass ViewModel {
val myState: StateFlow<Int>
field = MutableStateFlow(0)
get() = field.asStateFlow()
}
Trying to cast results in ClassCastException
as intended.
The syntax for this isn't really bad, but this is already 3 lines long, so IDK, maybe allowing this in the initializer would still be a good idea?Daniel Pitts
08/12/2024, 1:14 AMJoffrey
08/12/2024, 8:43 AMasStateFlow()
? On the JVM, people can do all sorts of things by reflection, so you can't really protect your code from people who actually want to break it. If people use as
on purpose, they're looking for trouble, I don't see a huge point in trying to prevent it. The most important IMO is to prevent accidental misuse, so the most important to me is to expose a read-only type so people don't actually mutate it.Skaldebane
08/12/2024, 12:25 PM