2017-02-06 55 views
5

我有以下2个代码片段;第一个给我没有问题,但对于第二个(追加到函数列表中),我收到一条错误消息。这两个之间有什么区别,我如何解决第二个问题?Scala:将元素添加到列表中

这一个正常工作:

object MyApp extends App 
{ 
    var myList = List.range (1, 6) 
    myList ::= 6  
    println(myList) 
} 

这不起作用:

def myFunc(list:List[Int]):Unit = 
    { 
     list ::= 10 
    } 


error: value ::= is not a member of List[Int] 
     list ::= 10 
      ^
one error found 

回答

2

我假设你是一名Java程序员,这就是为什么你有问题来理解问题所在。在Java中,如果尝试更改列表,即使在方法中,也可以这样做,因为没有创建新集合;它是添加元素的同一个集合。

但是,在Scala中,因为List本身不可变,所以需要创建一个全新的列表,因此需要重新分配指向列表的变量。由于在Scala中,传入的参数是val,因此重新分配会导致问题。在你的第一个代码中,创建了一个新的列表,但是因为list是一个var,所以这个重新分配不会引起任何问题。

如果列表本身是可变的,那么您在第二个代码块中没有问题,因为您不需要重新分配给列表。为了证明这一点,在第二个代码块中使用ListBuffer而不是List,并且您会看到它完美地工作。

+0

我认为这正是我的问题所在。在Java中,即使指向列表的变量是最终的,由于List类是可变的,这仍然不会造成问题。 – user1888243

6

标有var变量是可变的,因此可以被重新分配。 a ::= b运营商只是syntactic sugar由编译器提供的var变量。它执行操作a = b :: a。下面是一个例子:

scala> var l1 = List(1,2,3) 
l1: List[Int] = List(1, 2, 3) 

scala> l1 ::= 4 

scala> l1 
res1: List[Int] = List(4, 1, 2, 3) 

scala> val l2 = List(1,2,3) 
l2: List[Int] = List(1, 2, 3) 

scala> l2 ::= 4 
<console>:9: error: value ::= is not a member of List[Int] 
       l2 ::= 4 
       ^
scala> val l3 = 4 :: l2 
l3: List[Int] = List(4, 1, 2, 3) 

传递的参数是不可变的,因此操作者::=不能使用。

+1

因此,错误消息“value :: =不是List的成员”是错误的,或者至少没有帮助。它应该说像列表这样的东西是不可变的,因此不能被分配给。我的意思是::并没有突然停止成为可以在列表中使用的运营商。 – user1888243

+2

我想这可能会更有用,但它没有错。 ':: ='不是'List'的元素,但它被编译器转换为'a = b :: a'。 –