Kotlin:mutableList应该声明为Val还是Var?

时间:2019-06-20 15:54:50

标签: kotlin

我正在为团队阅读现有的代码库,并且我注意到mutableListOf始终声明为val。在某些情况下,元素仅一次添加到mutableListOf中。例如

val jobList = mutableListOf<JobActivity>()
jobList.addAll(job.activities)

在其他情况下,元素会循环添加到mutableListOf中。例如

val jobList = mutableListOf<JobActivity>()
newJobList.filterScanType(retrieveJobType(JobContext.NEW)).forEach {
    jobList.add(it)
}

由于列表在创建时未初始化,为什么不将mutableListOf声明为var?在网上找到的许多示例也遵循与mutableListOf一样声明val的模式。

valvar所述的两种情况下,最好使用哪种?

6 个答案:

答案 0 :(得分:4)

我认为它被声明为val,因为列表总是相同的,唯一改变的是它的元素。您将永远不会做类似的事情:

joblist = anotherList

正如@Taseer所说,即使它是一个val,也可以更改对象的属性。例如:

data class Example(var name: String)

val exampleObject = Example("SomeName")

您仍然可以这样做:

exampleObject.name = "AnotherName"

但是您不能这样做:

exampleObject = anotherObject

答案 1 :(得分:2)

val由于其他答案和评论中给出的原因而更加惯用。

您说val没有被实例化,但是在您的示例代码中它是实例化的。

val jobList = mutableListOf<JobActivity>()

是实例化空MutableList<JobActivity>

的工厂

使用此模式(在声明时实例化为val而不是var)可确保您的代码永远不会为jobList找到未初始化或空值;编译器可以证明这一点。

答案 2 :(得分:2)

使用Kotlin时的一般经验法则。

val和var的差异

您可能已经知道它们之间的区别,但是为了给出答案,我将重复一下。 var允许您修改对象的引用,而val不允许更改对象的引用。

可以使用varval关键字安全地声明对象,但是要在对象上使用val的原因(在大多数情况下) )是您不想用一个对象的新实例的新引用来引用该类成员。这样,您始终可以保留对原始对象的引用,并且可以修改对象属性。

对于var来说,尽管没有问题,但是您仍然可以“毫无问题”地使用它。您仍然可以访问对象属性并对其进行修改,还可以将该类成员引用到新对象的引用。

示例:

val myObject = MyObject()
myObject.something = 1 //can still modify object property.
myOjbect = MyObject() //re-referencing the object, NOT POSSIBLE


var myNewObject = MyNewObject()
myNewObject.someThing = "Hello world!" //can still modify object properties
myNewObject = MyNewObject()  //can still reference it.

如果对象不可变,为什么要在var上使用val?

它为您提供了避免“意外”放置新引用的安全性。

但是使用val有什么性能上的好处?

答案Final keyword benefit

答案 3 :(得分:1)

简而言之-没有规则,由您自己决定

如果您使用val,则可以修改mutableList,但不能重新分配

如果需要将另一个列表重新分配给同一变量,请使用var。在大多数情况下,您不需要它,这就是您的团队频繁使用它的原因

答案 4 :(得分:1)

变量是var还是val区分可以更改其值(引用)(var =可变)(val =不变)。

您应该始终在val上使用var以避免不必要的副作用(例如,在另一个线程中进行更改)。

在使用MutableList的情况下,您很可能应该使用val,因为您不想更改对列表的引用,而是要更改其内容。

以下是您的选项的概述:

// Do you want to change its reference (r) / contents (c)?
var a = mutableListOf(1, 2, 3) // r = yes, c = yes
var b = listOf(1, 2, 3)        // r = yes, c = no
val c = mutableListOf(1, 2, 3) // r = no,  c = yes
val d = listOf(1, 2, 3)        // r = no,  c = no

答案 5 :(得分:0)

您使用可变的var创建变量(可以更改)。可变意味着变量可以在将来更改。

val用于将来不会更改变量(表示常量或最终变量)时。

此处更改意味着新值或新事物将分配给变量,但

val list = mutableListOf()

在此列表变量中,您分配了可变列表。您刚刚更改了列表的值。但是您没有为刚添加的变量分配新实例或新值,也没有从列表中删除值。而已。因此,列表本身是不可变的。

如果您执行以下操作,这将是可变的...

var list = mutableListOf()
list = mutableListOf()

对同一变量进行两次初始化。