I would have expected this to work: ```val str = "...
# stdlib
d
I would have expected this to work:
Copy code
val str = "some-string"
val (key: String, value: String?) = str.split('=', limit = 2)
// value should contain null -- but this crashes saying it tried accessing the list's 1 index which doesn't exist...
does that make any sense? I'm not sure this is really possible though -- and if the
String?
is not specified, then I would have expected it to default to
String
and crash... otherwise this kind of thing could cause subtle bugs... (?)
r
val (x, y, ...) = a
is basically just a syntax sugar for:
Copy code
val x = a.component1()   // returns 1st element
val y = a.component2()   // returns 2nd element
...
So what you are looking at is what types do component functions of
str.split('=', limit = 2)
return? Well it's a
List<String>
but since a list can't know it's length on compile time, then the
List<T>
implementation has 2 choices: 1. all
componentX()
functions return
T?
- which would make the destructuring syntax basically unusable due to additional checks needed by caller 2. all
componentX()
return
T
and throw if they are out of bounds, which can lead to suprise exceptions (this is how it's implemented) Neither of them is ideal, but there is no better alternative, as the type would have to depend on runtime values
d
Yeah, I guess there couldn't be two versions of
componentX()
one nullable and one not... that's really what I was looking for, then the compiler would decide which one according to if
y
is nullable or not...
e
you could create a wrapper such as
Copy code
class OrNull<E>(val list: List<E>)
fun <E> List<E>.orNull() = OrNull(this)
operator fun <E> OrNull<E>.component1() = list.getOrNull(0)
operator fun <E> OrNull<E>.component2() = list.getOrNull(1)
Copy code
val (key, value) = str.split('=', limit = 2).orNull()
although they'd both be nullable
this is one of those cases where Scala's pattern matching would work out:
Copy code
var (key, value) = str.split("=", 2) match {
  case Array(key, value) => (key, value)
  case Array(key) => (key, null)
}
but Kotlin doesn't have anything similar yet (https://youtrack.jetbrains.com/issue/KT-186)
d
I guess that could even be a value class, that's a nice idea!