我是Scala的初級實踐者,我看到了一些調用方法的不同語法。有些是不錯的,因爲忽略了無參數方法的括號,或者忽略了這個點,但有些真的讓我困惑。例如:Scala - 方法調用語法
breakable { ... }
這只是一個方法調用權嗎?我也可以爲多個參數或不是無參數函數的參數做到這一點嗎?
感謝
我是Scala的初級實踐者,我看到了一些調用方法的不同語法。有些是不錯的,因爲忽略了無參數方法的括號,或者忽略了這個點,但有些真的讓我困惑。例如:Scala - 方法調用語法
breakable { ... }
這只是一個方法調用權嗎?我也可以爲多個參數或不是無參數函數的參數做到這一點嗎?
感謝
還有的調用方法兩種標準方式:
obj.method(params) // dot notation
obj method (params) // operator notation
上面可以通過以下方式修改:
params
是單個參數,則可以用{}
代替()
。params
是單參數和您正在使用操作符表示法,則可以刪除括號。method
不帶參數,則可以刪除(params)
(即刪除空的()
)。method
以:
結尾,則它實際上以運算符綁定到正確的。也就是說,(params) method_: obj
相當於obj.method_:(params)
。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)
如果:
method
被導入範圍。注意,有一個優先發布爲好。如果你寫obj method(params)
,即使它被導入到範圍中,斯卡拉將假定method
屬於obj
。
很棒的回答。我只是有一個關於你的點數1的問題,關於能夠用{}符號而不是()來調用一個方法。這個語法有什麼特定的原因嗎?這個語法似乎在許多框架和他們記錄的例子中經常使用。我想知道這個特定的語法是否支持一個非常具體的功能原因。它通常在將閉包作爲參數傳遞給函數時使用?我想了解它的根源,以便我能夠清楚地理解並推理它。謝謝。 – HiChews123 2016-08-12 03:33:37
@ acspd7嗯,'()'和'{}'在_expression_中有不同的含義。也就是說,'2 *(3 + 4)'和'2 * {3 + 4}'具有相同的結果,但是不同的東西。只能將表達式放在括號內,而將_definitions_和_statements_放在大括號內,而最後一個語句的值是它的表達式值(大括號本身就是表達式)。 f(...)'可以用'f {...}替換的原因就是人們不必寫'f({...})'。這允許人們編寫看起來很原生的「用戶」控制結構。 – 2016-08-12 22:29:54
如果我們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
以上是令行禁止函數的例子
是的,這是一個封閉。你正在將一個代碼塊傳遞給一個方法。請注意,在Scala中,您可以使用{}代替(),將單個參數傳遞給方法 – aishwarya 2012-08-10 09:54:19
這裏有什麼讓您煩惱?它是方法名稱之後的代碼塊('{...}')還是我們不用方法前綴對象/類名稱的事實? – Nicolas 2012-08-10 09:55:33