2012-08-10 83 views
10

我是Scala的初級實踐者,我看到了一些調用方法的不同語法。有些是不錯的,因爲忽略了無參數方法的括號,或者忽略了這個點,但有些真的讓我困惑。例如:Scala - 方法調用語法

breakable { ... } 

這只是一個方法調用權嗎?我也可以爲多個參數或不是無參數函數的參數做到這一點嗎?

感謝

+2

是的,這是一個封閉。你正在將一個代碼塊傳遞給一個方法。請注意,在Scala中,您可以使用{}代替(),將單個參數傳遞給方法 – aishwarya 2012-08-10 09:54:19

+0

這裏有什麼讓您煩惱?它是方法名稱之後的代碼塊('{...}')還是我們不用方法前綴對象/類名稱的事實? – Nicolas 2012-08-10 09:55:33

回答

22

還有的調用方法兩種標準方式:

obj.method(params) // dot notation 
obj method (params) // operator notation 

上面可以通過以下方式修改:

  1. 如果params是單個參數,則可以用{}代替()
  2. 如果params是單參數您正在使用操作符表示法,則可以刪除括號。
  3. 如果method不帶參數,則可以刪除(params)(即刪除空的())。
  4. 如果method:結尾,則它實際上以運算符綁定到正確的。也就是說,(params) method_: obj相當於obj.method_:(params)
  5. 無論哪種方式,只要標識符可以分開,空格是可選的。因此,可以在點符號上添加空格,例如obj . method (params)或在下一行寫.method(params)(如經常發生的調用鏈接),以及從操作符表示中刪除空格,如a+b中所示。

還有一些元組推理的東西,但我儘量避免它,所以我不確定確切的規則。

但是,這些都不能解釋您困惑的例子。在我解釋它,但是,我想證明,也可用於調用方法的一些語法糖:

obj(params) // equivalent to obj.apply(params) 
obj.x = y // equivalent to obj.x_=(y), if obj.x also exists 
obj(x) = y // equivalent to obj.update(x, y) 
obj op= y // equivalent to obj = obj op y, if op is symbolic 
~obj  // equivalent to obj.unary_~; also for !, + and -, but no other symbol 

好了,現在你給的例子。一個可以進口穩定值的成員。 Java可以通過靜態導入來實現靜態方法,但是Scala具有更一般的機制:從包,對象或通用實例導入沒有什麼不同:它帶來了類型成員和值成員。方法屬於後一類。

所以,想象你有val a = 2,你做import a._。這將涉及範圍全部Int方法,所以你可以直接打電話給他們。你不能這樣做+(2),因爲這會被解釋爲unary_+一個電話,但你可以叫*(4),例如:

scala> val a = 2 
a: Int = 2 

scala> import a._ 
import a._ 

scala> *(4) 
res16: Int = 8 

現在,這裏的規則。您可以撥打

method(params) 

如果:

  1. method被導入範圍。
  2. 你保持括號(即使只有一個參數)

注意,有一個優先發布爲好。如果你寫obj method(params),即使它被導入到範圍中,斯卡拉將假定method屬於obj

+0

很棒的回答。我只是有一個關於你的點數1的問題,關於能夠用{}符號而不是()來調用一個方法。這個語法有什麼特定的原因嗎?這個語法似乎在許多框架和他們記錄的例子中經常使用。我想知道這個特定的語法是否支持一個非常具體的功能原因。它通常在將閉包作爲參數傳遞給函數時使用?我想了解它的根源,以便我能夠清楚地理解並推理它。謝謝。 – HiChews123 2016-08-12 03:33:37

+2

@ acspd7嗯,'()'和'{}'在_expression_中有不同的含義。也就是說,'2 *(3 + 4)'和'2 * {3 + 4}'具有相同的結果,但是不同的東西。只能將表達式放在括號內,而將_definitions_和_statements_放在大括號內,而最後一個語句的值是它的表達式值(大括號本身就是表達式)。 f(...)'可以用'f {...}替換的原因就是人們不必寫'f({...})'。這允許人們編寫看起來很原生的「用戶」控制結構。 – 2016-08-12 22:29:54

15

如果我們desugar這一點,我們將有:

breakable({ ... }) 

此相匹配的簽名

breakable: (op: ⇒ Unit): Unit 

和使用如此命名的call-by-名參數(你也許會想這個作爲通過一段代碼作爲參數

更多在斯卡拉允許你這樣寫:

scala> def foo (op1: => Unit)(op2: => Unit) = {op1;op2;} 
foo: (op1: => Unit)(op2: => Unit)Unit 

scala> foo { println(1) } { println(2) } 
1 
2 

以上是令行禁止函數的例子