Meika
02/20/2024, 4:53 PMStateFlowImpl
by using Symbol
(LoC in context) but its an internal coroutines API and marked as an unstable API
private var _value: T = // need to set default value here but can't be null
override var value: T
get() = _value
set(value) {
if (disabled) throw IllegalStateException("Can not set value to $value as bindable is disabled.")
if (value?.equals(_value) == true) return
setValue(_value, value)
}
Joffrey
02/20/2024, 4:55 PMT
accept nullable types? (meaning, can the user use nullable types as T
/ does it make sense in your case?)Meika
02/20/2024, 4:56 PMT
accept nullable, yesJoffrey
02/20/2024, 4:57 PMvalue?.equals(_value)
a valid test? It seems the user will not be able to set null
in this case. If you already don't allow users to set null, you could forbid it entirely by adding the : Any
bound to your T
, and then use the T?
type for your backing field, and null as your default value (or use lateinit)Joffrey
02/20/2024, 4:58 PMJoffrey
02/20/2024, 5:00 PMsealed class MyValue<out T> {
data object Unset : MyValue<Nothing>()
data class Set<T>(val value: T): MyValue<T>()
}
But that might be quite overkill depending on what your use case isMeika
02/20/2024, 5:05 PMvalue?.equals(_value)
is just me trying to skip the setValue
if the new value is the same as current value.Meika
02/20/2024, 5:05 PMYou might need to get the default from the user depending on what your code is doingaha so it implies that end user should set the initial value instead?
Joffrey
02/20/2024, 5:06 PMJoffrey
02/20/2024, 5:06 PMnull
. Why not use value == _value
?Meika
02/20/2024, 5:24 PM_value
from start), and the next goal is throwing an exception if user try to query the value when it's not initialized. I initially set the _value
as null, but it also implies the T
is "always" nullable since value
will become T?
.
sounds a bit weird usecase sure but I'm trying to make it looks same as the original API I tried to port here.
so yeah tl;dr is basically i want to set default value of T
"internally" without needing user to set the value.
full code for more context.Meika
02/20/2024, 5:24 PMvalue == _value
should be used here. need to cover more on my test.Joffrey
02/20/2024, 5:30 PM_value
becomes T?
, but value
can stay T
if you write the getter to fail when _value
is null (access to uninitialized value). But indeed that means you can no longer support null as a valid value for users.
So, in short:
• if you don't need to support null as a valid value for users, just add a non-nullable bound on T
with T : Any
, and use lateinit.
• if you do need to support null as a valid value for users, keep your T
general like this, but use a sealed class as shown above to represent the uninitialized value. If you're worried about the performance of the sealed class, you could also choose to use an unsafe Any?
type for _value
, use an arbitrary object to represent your uninitialized value, and use unsafe casts locally (hidden in your getter/setter).Meika
02/20/2024, 5:50 PM