2015-10-04 22 views
4

嘿,我有如下一段代碼:Scala中的apply()函數給出編譯錯誤?

var z:Array[String] = new Array[String](4); 
z(0) = "Dave"; 
z(1) = "Joe"; 
z(2) = "Jim"; 
z.apply(3) = "Roger"; 

最後一行這裏是給編譯時錯誤說 - 「丟失的論據方法適用於Array類;按照這個方法用'_」,如果你想把它當作一個部分應用的函數「

這對我來說沒有意義,因爲我已經讀過,當你將一個多個值的括號應用於一個變量時,Scala會將代碼轉換爲一個名爲適用於該變量。 因此,如果下面一行:

z(2) = "Jim"; 

被轉換爲

z.apply(2) = "Jim"; 

那麼爲什麼行

z.apply(3) = "Roger"; 

給我一個編譯時錯誤?

我是新的斯卡拉,所以任何幫助將非常感謝!

+0

有趣的問題,由於'陣列#apply' [文檔](http://www.scala-lang.org/api/current/ index.html#scala.Array)狀態:'指數從0開始; xs.apply(0)是數組xs的第一個元素。請注意,索引語法xs(i)是xs.apply(i)的縮寫。# –

+0

您正在做的事情是對'update'進行除糖,而不是'apply'。 'update'的文檔類似:​​'索引從0開始; xs.update(i,x)替換數組中的第i個元素。請注意語法xs(i)= x是xs.update(i,x)的簡寫形式。' – Shadowlands

回答

7

這一呼籲:

z(2) = "Jim"; 

被轉換到

z.update(2, "Jim") 

apply當您嘗試賦值不起作用。

更新

你可以自己去查。在控制檯中運行:scala -printval ar = Array(1, 2, 3)

然後,當您輸入下一行ar(2) = 5時,它會顯示生成的代碼。這是一個有點複雜(翻譯增添了不少的東西,爲它自己的目的),但你將能夠找到這個(或類似)行:

$line3.iw.ar().update(2, 5); 
+0

如何顯示脫糖 - 僅通過查看字節碼? –

+1

@KevinMeredith請參閱我的更新。這是關於scala代碼而不是字節碼的 - 我們不必深入瞭解它是如何翻譯的 – Archeg

+0

瞭解它,謝謝你的回答! – fulhamHead

2

Scala Language Specification - Section 6.15覆蓋該徹底:

具有=運算符左側的函數應用程序的賦值f(args) = e被解釋爲f.update(args, e),即調用由f定義的update函數。

所以,換句話說,編譯器

z(i) = "Name"改變分配語法的可變數組zz.update(i, "Name")

z.apply(3) = "Roger"不包括在本特定的規則,所以這是行不通的。從規範


分配語法包括:

assignment  expansion 

x.f = e   x.f_=(e) 
x.f() = e  x.f.update(e) 
x.f(i) = e  x.f.update(i, e) 
x.f(i, j) = e x.f.update(i, j, e)