`if (someArray[x] != null) { someArray[x].add(foo)...
# getting-started
d
if (someArray[x] != null) { someArray[x].add(foo) }
Why does the compiler not recognize that
someArray[x]
cannot be null, and insists on
!!
?
k
Do why mean why it doesn't recognize that
someArray[x]
is not null? The compiler is very conservative about smartcasting, for example in this case another thread might have modified the array inbetween.
m
You can do
someArray[x]?.let { it.add(foo) }
.
d
@karelpeeters in this case, that wouldn't be possible, as I define the
someArray
right before the if statement. Would checking if other threads have access to the variable not be an option for the compiler?
@marstran thanks, unfortunately I cannot, because I also need an
else
(where
someArray[x]  = mutableList()
)
m
Then I would just do this:
Copy code
val list = someArray[x] ?: mutableListOf()
list.add(foo)
someArray[x] = list
d
Thanks. I think the if/else solution is a bit more readable, however
t
public operator fun get(index: Int): E
Since it returns a non-nullable type, you will only ever receive the object at the given index or I believe a
IndexOutOfBoundsException
- it’s equal to
someArray.get(<index>)
To get a null from the accessor you need to either use
list.getOrNull(index)
or
List<(your type)?>
The first, you will get null if the index is out of bounds or if the type is nullable AND the value at the given index is null. The second, you will still get an out of bounds error if the index is out of bounds but if the value at that index is null, you will get a null. The second should be avoided - as it’s best practices to avoid nullable types whenever possible.
That said though, the pattern you seem to be using isn’t good for lists. You can only set
someArray[x]
if
someArray
is at least x long. For example,
Copy code
val list = mutableListOf(1,2,3)
list[3] = 2
will produce an
IndexOutOfBoundsException
k
No he's talking about an
Array<T?>
and the fact that the compiler doesn't smartcast elements.
d
Even though you defined
someArray
right before this statement, the compiler doesn't know if the method used to generate
someArray
kept a reference to that array and is mutating it in another thread. It was probably a library method that would never do something like that, but the compiler shouldn't know that.
👍 1