Котлин: изменение (неизменяемого) списка через cast, является ли это законным?
Как мы знаем, список в Котлине неизменен, т. е. вы не можете добавлять и удалять, как показано ниже.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
myList!!.add(10)
myList!!.remove(10)
}
}
но если мы бросим его в ArrayList, как показано ниже, добавление и удаление работает.
class TempClass {
var myList: List<Int>? = null
fun doSomething() {
myList = ArrayList<Int>()
(myList!! as ArrayList).add(10)
(myList!! as ArrayList).remove(10)
}
}
Я просто подумал, что это странно, так как myList-это действительно список, который должен быть неизменным. И бросая его, позвольте ему быть измененным.
является ли то, что сделано выше (приведение к массиву и изменению содержимого) законным, или язык должен улучшиться, чтобы запретить это?
3 ответов
существует несколько различных типов неизменности:
один упоминается из отдельного ответа SO здесь.
Readonly-вы не должны изменять его (список Котлина), но что-то может (приведение к изменяемому или изменение с Java).
List
- Это просто интерфейс, который не имеет методов мутации, но вы можете изменить экземпляр, если вы приведете его к MutableList
.
кто-то затем переходит к комментарию, что Котлин решил быть только для чтения, чтобы использовать коллекции Java напрямую, поэтому нет никаких накладных расходов или преобразования в использовании коллекций Java.
список Котлина только для чтения, а не неизменяемый. Другие абоненты (например, Java) могут изменить список. Звонившие из Котлина могли составить список и изменить его. Нет непреложной защиты.
Источник: Котлин и неизменяемые коллекции?
это нормально? Ну да. Есть случаи использования, в которых это имело бы смысл.
это хорошая идея? Я думаю, что нет, особенно если вы говорите о приведении списка, который был возвращен какой-то внешней библиотекой. Бросок не удастся, если кто-то вручает вам подарки!--0--> реализации, которые действительно неизменяемы и не реализуют MutableList
. Дело в том, что на данный момент (Котлин 1.0.2), все Котлина Lists
также MutableList
s не означает, что каждый List
вы когда-нибудь увидите, что в вашем коде также есть MutableList
.
Если вы используете listOf () вы получите список со всеми методами, которые мутируют список, бросая java.ленг.UnsupportedOperationException:
val list = listOf(1, 2)
val mlist = list as MutableList
mlist.add(3)
этот броски:
Exception in thread "main" java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)