allan.conda
11/26/2020, 5:07 PMnull
in Kotlin?
fun <T> aFunctionWithOptionalParam(
optionalParam: T? = null
) {
if (/* optionalParam is set*/) {
someCallbackIfSet()
}
}
fun whatIWant() {
aFunctionWithOptionalParam(1) // callback is invoked
aFunctionWithOptionalParam(null) // callback is invoked
aFunctionWithOptionalParam() // callback should not be invoked
}
wbertan
11/26/2020, 5:10 PMNothing
?allan.conda
11/26/2020, 5:12 PMVampire
11/26/2020, 5:12 PMnull
really means not set.Vampire
11/26/2020, 5:13 PMOptional
should never be used as parameter or field type, only as return type of methodsNir
11/26/2020, 5:15 PMNir
11/26/2020, 5:16 PMNir
11/26/2020, 5:16 PMNir
11/26/2020, 5:17 PMNir
11/26/2020, 5:17 PMVampire
11/26/2020, 5:19 PMVampire
11/26/2020, 5:21 PMVampire
11/26/2020, 5:21 PMNir
11/26/2020, 5:23 PMallan.conda
11/26/2020, 5:24 PMVampire
11/26/2020, 5:24 PMfun aFunctionWithOptionalParam() =
aFunctionWithOptionalParamDelegate(null, false)
fun <T> aFunctionWithOptionalParam(optionalParam: T?) =
aFunctionWithOptionalParamDelegate(optionalParam, true)
private fun <T> aFunctionWithOptionalParamDelegate(
optionalParam: T?,
paramGiven: Boolean
) {
if (paramGiven) {
someCallbackIfSet()
}
}
allan.conda
11/26/2020, 5:26 PMaFunctionWithOptionalParamDelegate<Any>()
allan.conda
11/26/2020, 5:27 PM<Nothing>
would be more approriate I thinkallan.conda
11/26/2020, 5:27 PMallan.conda
11/26/2020, 5:30 PMVampire
11/26/2020, 5:30 PMVampire
11/26/2020, 5:31 PMNothing
allan.conda
11/26/2020, 5:35 PMparamGiven
and the other function not having <T>
. Niceallan.conda
11/26/2020, 5:36 PMfun <T> aFunctionWithOptionalParam(
optionalParam: T
) {
optionalParam?.run {
someCallbackIfSet()
}
codeIDontWantToDuplicate()
}
fun aFunctionWithOptionalParam() {
codeIDontWantToDuplicate()
}
fun codeIDontWantToDuplicate(
) {}
fun codeIDontWantToDuplicate() {}
fun whatIWant() {
aFunctionWithOptionalParam(optionalParam = 1) // code is run
aFunctionWithOptionalParam(optionalParam = null) // code is run
aFunctionWithOptionalParam() // optional code is not run
}
Vampire
11/26/2020, 5:39 PMVampire
11/26/2020, 5:41 PMcodeIDontWantToDuplicate
stuff directly within aFunctionWithOptionalParam()
and then call aFunctionWithOptionalParam()
from within aFunctionWithOptionalParam(T)
after doing the optional action, then you don't need the extra codeIDontWantToDuplicate()
allan.conda
11/26/2020, 5:42 PMallan.conda
11/26/2020, 5:45 PMVampire
11/26/2020, 5:46 PMbezrukov
11/26/2020, 7:12 PMAny?
Instead of T?
then as a default value you can use NULL = Any()
One drawback here that you will loose compile time check that optional param is T?
Vampire
11/26/2020, 7:51 PMallan.conda
11/26/2020, 7:58 PMbezrukov
11/26/2020, 9:00 PMcallback.invoke(param as T?)
allan.conda
11/26/2020, 9:14 PMallan.conda
11/26/2020, 9:15 PMCLOVIS
11/26/2020, 10:21 PMNone
is Kotlin's Unit
, but without union types that doesn't really solve your issue (however the Kotlin Arrow library has union types but I don't think it's stable yet?)Nir
11/26/2020, 10:21 PMCLOVIS
11/26/2020, 10:22 PMNir
11/26/2020, 10:23 PMNir
11/26/2020, 10:23 PMNir
11/26/2020, 10:24 PMtrathschlag
11/26/2020, 10:33 PMfun <T> aFunctionWithOptionalParam(
optionalParam: T? = null
) {
funInternal(NullableOptional.Value(optionalParam))
}
fun aFunctionWithOptionalParam() {
funInternal(NullableOptional.Empty)
}
private sealed class NullableOptional<T> {
data class Value<T>(val value: T) : NullableOptional<T>()
object Empty : NullableOptional<Nothing>()
}
private fun <T> funInternal(optional: NullableOptional<T>) {
if (optional is NullableOptional.Value) {
if (optional.value != null) {
// handle value
} else {
// handle null
}
} else {
// handle no value
}
}
allan.conda
12/10/2020, 5:52 PMval hasSavedValue = contains(key) // returns true even if null (value set)
val savedOrInitialValue: T = if (hasSavedValue) {
get(key)!! // returns `T?`
// will above work the same as `requireNotNull(get(key))` ?
} else { initialValue }
This time I always know there is an initialValue, but I don’t want to use initialValue if there is a saved value, even if the saved value is null.
Is this the right way to do it? Or will !!
throw an exception for any null (even if it’s expected)?Nir
12/10/2020, 5:54 PMMap
right?Nir
12/10/2020, 5:54 PMgetOrDefault
?Vampire
12/10/2020, 5:59 PMget(key)!!
will throw an exception if get(key)
returned null
.
requireNotNull(key)
will throw an exception if key
is null
.allan.conda
12/10/2020, 6:00 PMCouldn’t you just useAh… sh*t. It’s a Map but there a framework class wrapper on top of the it… I wish I could just use it?getOrDefault
@MainThread
@Nullable
public <T> T get(@NonNull String key) {
return (T) mMap.get(key);
}
allan.conda
12/10/2020, 6:00 PMrequireNotNull(get(key))
Vampire
12/10/2020, 6:01 PMVampire
12/10/2020, 6:01 PMnull
in the map for the key?Nir
12/10/2020, 6:01 PMallan.conda
12/10/2020, 6:02 PMNir
12/10/2020, 6:02 PMVampire
12/10/2020, 6:02 PM!!
then?allan.conda
12/10/2020, 6:02 PMNir
12/10/2020, 6:02 PMallan.conda
12/10/2020, 6:02 PMVampire
12/10/2020, 6:03 PMif (containsKey(key)) get(key) else initialValue
Nir
12/10/2020, 6:03 PMNir
12/10/2020, 6:03 PMNir
12/10/2020, 6:03 PMallan.conda
12/10/2020, 6:03 PMVampire
12/10/2020, 6:04 PMNir
12/10/2020, 6:04 PMVampire
12/10/2020, 6:04 PMNir
12/10/2020, 6:05 PMNir
12/10/2020, 6:05 PMNir
12/10/2020, 6:05 PMallan.conda
12/10/2020, 6:05 PMNir
12/10/2020, 6:06 PMNir
12/10/2020, 6:06 PMNir
12/10/2020, 6:07 PMNir
12/10/2020, 6:08 PMval hasSavedValue = contains(key)
val savedOrInitialValue: T = if (hasSavedValue) getValue(key) else initialValue
allan.conda
12/10/2020, 6:08 PMNir
12/10/2020, 6:08 PMallan.conda
12/10/2020, 6:08 PMallan.conda
12/10/2020, 6:08 PMallan.conda
12/10/2020, 6:09 PMNir
12/10/2020, 6:09 PMNir
12/10/2020, 6:09 PMallan.conda
12/10/2020, 6:09 PMNir
12/10/2020, 6:10 PMNir
12/10/2020, 6:10 PMallan.conda
12/10/2020, 6:11 PMallan.conda
12/10/2020, 6:12 PMallan.conda
12/10/2020, 6:12 PMNir
12/10/2020, 6:15 PMallan.conda
12/10/2020, 6:21 PM@Nullable
on the wrapper get
function. -_-, would have worked otherwise.allan.conda
12/10/2020, 6:23 PM