Я всегда предполагал, что List
в Kotlin неизменяемый, но, когда писал другой пост, я узнал, что технически он доступен только для чтения, а не неизменяем, так как на самом деле его можно изменить с помощью нескольких методов.
MutableList
является подклассом List
, и когда MutableList
назначается List
, он все еще может быть изменен с использованием ссылки на MutableList
.
List
также можно преобразовать в MutableList
, а затем изменить. Это означает, что если вы передадите List
в другой метод, есть вероятность, что ваш исходный список будет изменен.
«Безопасный» способ изменить List
- использовать метод toMutableList()
. Это создает копию оригинального List
и возвращает MutableList
.
Однако одноэлементный List
, созданный с помощью listOf()
, неизменен. Однако обратите внимание, что это не обнаруживается во время компиляции.
В стороне: эта разница по дизайну, из-за того, как Kotlin представляет List в Java. Если мы декомпилируем в Java, за кулисами произойдет вот что:
val list1 = listOf(1) val list2 = listOf(1, 2) ...becomes... @NotNull private static final List list1 = CollectionsKt.listOf(1); @NotNull private static final List list2 = CollectionsKt.listOf(new Integer[]{1, 2}); ...and CollectionsKt.listOf is... public fun <T> listOf(element: T): List<T> = java.util.Collections.singletonList(element)
java.util.Collections.singletonList
неизменен! Но поскольку многоэлементные списки создаются как массив, это фактически делает его изменяемым.
Как было сказано выше, если мы используем только List
в коде Kotlin, а не назначаем его или приводим к MutableList
, или передаем его на или из Java, то его можно смело назвать неизменяемым, поскольку в нем нет set()
или add()
методы.
Привет, если вам понравился этот пост, я подумал, что вы могли бы заинтересоваться членством в Medium, чтобы получить доступ к качественному контенту от авторов Medium, не стесняйтесь использовать мою реферальную ссылку! Вам также могут понравиться эти футболки с дизайном, вдохновленным кодом.