Introduction
The Day 4 problem might be seen as a business problem that requires reading some input data from the user, parsing it and performing business transformations.
We can try to realize that using some readable approach with the usage of extension functions and defining a few
typealiases
es which would express our intentions.
Solution
Let’s start with the code solution
|
|
Extra code comments
We should start with the input data format that is given in unusual way because particular passports can be defined in a few lines. Because of that we have to split the input on blank lines and concatenate the adjacent lines to each other to get the complete passport definitions.
Next we can convert the passport definitions into proper data structure that represents particular fields in passport with
Map<String, String>
. Using extension functions seems to be a good approach for this problem because we use
only some defined data structure (i.e. Map<String, String>
) without defining new class. Thanks to the Kotlin syntax
we can use them later by calling on particular passports objects. We know from Kotlin documentation
that these functions are implemented as syntax sugar static functions on JVM that take caller object as the first argument.
We can also observe that using great tool in Intellij IDE for showing some bytecode that corresponds to selected part of code.
To use it, it’s enough to select some function and call the action (with Ctrl + Shift + A
/Cmd + Shift + A
)
named Show Kotlin Bytecode
. Using that tool we see, that for example in case of the simplest Passport::hasFields
function
the compiled Kotlin bytecode looks like
|
|
The most interesting for us parts of this code are:
- function is declared as
static final
function - function takes a
Map
object as its argument and uses it later by callingALOAD 0
which strictly corresponds to our theoretical knowledge of the extension functions in Kotlin.
By the way, we can observe that the first part of this function is checking if it’s first argument (i.e. Passport
caller object) is null
or not, because it was defined as not nullable type. It’s worth recalling that these Kotlin
checks for nullability are not only the compiler checks, but they also result in extra checks in runtime of our code 😉