我们鼓励尽可能多地使用不可变变量。但是,如果我有时需要修改列表,我想知道我应该使用哪种方法......
val mutableList = mutableListOf()
,我可以在那里add
,remove
相应要么
var immutableList = listOf()
我会在每次更改时创建一个新列表(使用filter或+
)。我猜有一种不同的情景,一种比另一种更受欢迎。因此想知道何时应该使用其他等。
可变和不可变列表增加了模型的设计清晰度。 这是为了迫使开发人员思考和澄清收集的目的。
val
和var
的目的不同于不可变和可变列表。
val
和var
关键字谈论如何处理变量的值/引用。
var
- 分配给变量的值/引用可以在任何时间点更改。val
- 值/引用只能为变量赋值一次,并且在执行后的某个时间点不能更改。在Kotlin中将可变列表分配给val并向其添加元素是完全有效的。
val a = mutableListOf(1,2,3,4)
a.add(5)
println(a)
将输出
[1, 2, 3, 4, 5]
val - >你可能认为你不能为变量重新分配。
//that is ok
var a:Int = 1
a=2
//Even you can reassign but you can't change its type
a= "string" //that's wrong
//that is wrong
val b:Int = 1
b = 2
列表 - >你会认为你不能插入/删除/改变列表中的任何元素(不能对列表的内容做任何事情)
var list:List<Int> = listOf(1,2,3,4) //[1,2,3,4]
//you can read list
list.get(0)
list[0]
//but you can't change(/write) the content of the list (insert/delete/alter)
list.set(0, 100)
list.add(5)
list.removeAt(0)
var mutableList:MutableList<Int> = mutableListOf(1,2,3,4) //[1,2,3,4]
//you can read and write
mutableList.get(0)
mutableList.set(0, 100) //[100,2,3,4]
mutableList.add(5) //[100,2,3,4,5]
mutableList.removeAt(0) //[2,3,4,5]
结合他们两个,你会得到四个案例
案例1:var mutableList:MutableList = mutableListOf(1,2,3,4)
//you can reassign
mutableList = mutableListOf(4,5,6,7) //[4,5,6,7]
//you can alter the content
mutableList.set(0, 100) //[100,5,6,7]
mutableList.add(8) //[100,5,6,7,8]
mutableList.removeAt(0) //[5,6,7,8]
案例2:val mutableList:MutableList = mutableListOf(1,2,3,4)
//you can't reassign
mutableList = mutableListOf(4,5,6,7) //that's wrong
//you can alter the content
mutableList.set(0, 100) //[100,2,3,4]
mutableList.add(8) //[100,2,3,4,8]
mutableList.removeAt(0) //[2,3,4,8]
案例3:var list:List = ListOf(1,2,3,4)
//you can reassign
list= ListOf(4,5,6,7) //[4,5,6,7]
//you can't alter the content
list.set(0, 100) //that's wrong
list.add(8) //that's wrong
list.removeAt(0) //that's wrong
案例4:val列表:List = ListOf(1,2,3,4)
//you can't reassign
list= ListOf(4,5,6,7) //that's wrong
//you can't alter the content
list.set(0, 100) //that's wrong
list.add(8) //that's wrong
list.removeAt(0) //that's wrong
//the only thing you can do is Read
list.get(0) //return 1
list[0] //return 1
我猜有一种不同的情景,一种比另一种更受欢迎。因此想知道何时应该使用其他等。
有几个原因导致不可变对象通常更可取:
map
,filter
,reduce
等。你也有一些缺点:
copy()
方法,您可以在其中复制实例,同时仅为某些字段提供新值。您最终使用哪一个取决于手头的用例。对于数据类(将一些属性捆绑在一起),坚持不变性通常是个好主意。对于集合,如果你使用不可变的只是为了修改它们的副本并重新分配指向它们的引用,你也可以使用可变的副本。如果您将应用程序的许多部分共享一个依赖于状态保持不变的集合,请使用不可变。
请记住,Kotlin系列有不同的概念:
MutableList<T>, MutableSet<T>, MutableMap<T>
这些可以随时修改。List<T>, Set<T>, Map<T>
这些提供了集合的只读视图,即无法通过该引用修改集合。它不能保证不变性(对它的另一个可变引用仍然可以存在并用于修改)。ImmutableList<T>, ImmutableSet<T>, ImmutableMap<T>
这些将保证真正的不变性,并提供基于它们构建新修改集合的模式。有关详细信息,请参阅Proposal。