Kotlin:val可变列表与var不可变列表。什么时候用哪个?

Kotlin:val可变列表与var不可变列表。什么时候用哪个?,kotlin,immutability,mutable,Kotlin,Immutability,Mutable,我们被鼓励尽可能多地使用不可变变量 但有时当我不得不修改一个列表时,我开始怀疑哪种方法更适合当前的情况 val mutableList = mutableListOf() // where I can just .add() / .remove() accordingly 或 我想有不同的场景,一个比另一个好。 因此,我想知道什么时候应该使用一个而不是另一个,可变和不可变列表可以提高模型的设计清晰度 这是为了迫使开发人员思考并澄清收集的目的 如果集合将作为设计的一部分进行更改,请使用可变集合

我们被鼓励尽可能多地使用不可变变量

但有时当我不得不修改一个列表时,我开始怀疑哪种方法更适合当前的情况

val mutableList = mutableListOf()
// where I can just .add() / .remove() accordingly

我想有不同的场景,一个比另一个好。
因此,我想知道什么时候应该使用一个而不是另一个,可变和不可变列表可以提高模型的设计清晰度
这是为了迫使开发人员思考并澄清收集的目的

  • 如果集合将作为设计的一部分进行更改,请使用可变集合
  • 如果模型仅用于查看,请使用不可变列表
  • 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]
    
    我想有不同的场景,一个比另一个好。因此,我想知道什么时候应该使用一个,而不是另一个等等

    不可变对象之所以更可取,有几个原因:

    • 它们鼓励函数式编程,其中状态不会发生变化,而是传递给下一个函数,该函数基于状态创建新的状态。这在Kotlin收集方法中非常明显,如
      map
      filter
      reduce
    • 没有副作用的程序通常更容易理解和调试(可以确保对象的值始终是其定义的值)
    • 在多线程程序中,不可变资源不会导致竞争条件,因为不涉及写访问
    你也有一些缺点:

    • 仅为了添加/删除单个元素而复制整个集合在计算上非常昂贵
    • 在某些情况下,当您繁琐地需要更改单个字段时,不变性会使代码更加复杂。在Kotlin中,数据类带有一个内置的
      copy()
      方法,您可以在其中复制实例,同时只为某些字段提供新值
    最终使用哪一个取决于手头的用例。对于数据类(将几个属性捆绑在一起),坚持不变性通常是一个好主意。对于集合,如果您使用不可变集合只是为了修改它们的副本并始终重新分配指向它们的引用,那么您也可以使用可变集合。如果将一个集合共享给依赖于状态保持不变的应用程序的许多部分,请使用immutable

    请记住,Kotlin系列有不同的概念:

  • 可变集合:
    可变列表、可变集合、可变地图

    可以随时修改这些内容
  • 只读集合:
    列表、集合、映射

    它们提供集合的只读视图,即不能通过该引用修改集合。但它不能保证不变性(对它的另一个可变引用仍然可以存在并用于修改)
  • (提议,尚未成为Kotlin的一部分)
    不可变集合:
    不可变列表、不可变集合、不可变映射

    这些将保证真正的不变性,并提供基于它们构建新的修改集合的模式。有关详细信息,请参阅
  • val->您可能认为无法为变量重新赋值

    ListOf->您可能认为您不能插入/删除/更改列表中的任何元素 (无法对列表的内容执行任何操作)

    案例2:val-mutableList:mutableList=mutableListOf(1,2,3,4)

    案例3:var list:list=ListOf(1,2,3,4)

    案例4:val list:list=ListOf(1,2,3,4)


    也要注意
    val
    an
    var
    。如果您可以考虑使用VAL和var来详细阐述它,这将是有帮助的。您交换了VAL和VAR,VAL只能被分配一次,VAR可以是changed@Alowaniak我修好了;)
    [1, 2, 3, 4, 5]
    
    //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]
    
    //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]
    
    //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]
    
    //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
    
    //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