2017-02-06 254 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'。 –