@fatjoe79, what if all of the assignments give null
You’ ll need ensure not null via x!! at the end. Then yo kinda already have non-nullable type after this line via narrowing
This case looks kinda cool to me, but I’m not sure if having twin elvis assignments
a ?= b // for
if(a == null) a = b
//and
a =? b // for
if(b != null) a = b
ok, I think this way compiler could ensure non-nullability. but in this case it’ll have to look forward, not sure if this possible.
I think having var x: Foo? here is good enough since x will be narrowed after last conditional assignment anyway
Nope, at the moment of creation, I didn’t get a lot of likes, so I didn’t continue the topic.
The biggest part of the conversation was about if you needed to write everything as a one-liner
WDYT about this three elvises ?=, =? and ?=? ?
One of them would be familiar to groovy coders (the one that checks receiver), another one checking the message, and last one well for symmetry
They are for one-liners, to save one null check. Kinda like what elvis does
In my project I have a lot of untyped input data which needs to be assigned to typed DTOs before any further usage.
My final proposal for now is to make 3 new operators (one of which will be borrowed from groovy 3):
a ?= b // instead of
if(a == null) a = b
a =? b // instead of
if(b != null) a = b
a ?=? b // instead of
if(a == null && b != null) a = b
question mark here is on the side which is to be checked for null
Yeah, on second thought it kinda looks useless by itself. The only difference here is whether a setter should be called when null passed to a null receiver
so then let it be
a ?= b // instead of
if(a == null && b != null) a = b
a =? b // instead of
if(b != null) a = b
in case of ?= it will do the same as in groovy, assign default value, except assigning null as a default which is pointless
in case of =? its just ‘assign if there is something to assign’
and “there will be a null check on the side where ‘?’ is”
dunno, seems ok to me
Is it? Are we talking about the same code samples here?
If I understand you correctly you said that
// from fatjoe79
var x: Foo // I guess that would need to be Foo? = someInitlialValue
x ?= foo?.let{
// complex expression 1
}
x ?= bar?.let{
// complex expression 2
}
x ?= baz?.let{
// complex expression 3
}
is the same as
// from cabman
val x = foo?.let {
// complex expression 1
} ?: bar?.let {
// complex expression 2
} ?: baz?.let {
// complex expression 3
}
But based on my understanding the code @fatjoe79 posted translates to
var x: Foo? = someValue
if(x == null) x = foo?.let{ ... }
if(x == null) x = bar?.let{ ... }
if(x == null) x = baz?.let{ ... }