Derek Peirce
02/15/2020, 9:13 PMx
is an `Int`:
val y = x.takeIf { it > 5 } ?: 3
The compiled bytecode becomes:
Integer var2 = x;
int it = ((Number)var2).intValue();
int y = (it > 5 ? var2 : null) != null ? it > 5 ? var2 : null : 3;
This has some undesirable boxing and unboxing, it would be ideal if the compiler could optimize this to the equivalent of:
val y = if (x > 5) x else 3
which compiles in Java to:
int y = x > 5 ? x : 3;
What makes this particularly desirable? Consider the protobuf pattern: https://developers.google.com/protocol-buffers/docs/javatutorial#the-protocol-buffer-api
public boolean hasId();
public int getId();
To avoid boxing, primitives are stored with a default value, and a bitfield to indicate which primitives are truly set. Otherwise, we would ideally have a single method:
inline fun getId(): Int? = if (hasId()) getPrimitiveId() else null
It is inlined so that any boxing elimination could be carried out across method calls. If the compiler could eliminate unnecessary boxing, then this call:
if (proto.hasId()) proto.getId() else calculateDefault()
could be replaced with the more straightforward:
proto.getId()?: calculateDefault()
Fleshgrinder
02/15/2020, 10:13 PMnull
and has no has
method for scalar types (they had in Proto2 if I recall correctly). That said, you're request makes perfect sense. I think there is a lot of room to improve the compiler output.Derek Peirce
02/15/2020, 10:16 PMnull
in place of requiring has
followed by get
. From my link, you can see the hasId
method, what does would it have in Proto3?Fleshgrinder
02/16/2020, 9:52 AMoptional
and required
do not exist anymore. An int32
always gives you 0
if it was not set. You have to use a message if you want to know if it is present or not.