2009-09-27 162 views
68

我在哪裏可以找到斯卡拉的「魔術」功能列表,如apply,unapply,update,+=等。斯卡拉的「魔術」功能列表

通過魔法功能我指的是通過編譯器的一些語法糖的功能,例如

o.update(x,y) <=> o(x) = y 

我用Google搜索的scalamagicfunctions同義詞一些組合,但我沒有找到任何東西。

我對標準庫中魔術函數的使用不感興趣,但其中存在魔術函數。

回答

71

據我所知:

getter/setter方法有關:

apply 
update 
identifier_= 

模式匹配:

unapply 
unapplySeq 

對於-內涵:

map 
flatMap 
filter 
withFilter 
foreach 

前綴運營商:

unary_+ 
unary_- 
unary_! 
unary_~ 

除此之外,任何隱含的從A到B的Scala也將轉換成A <op>= BA = A <op> B,如果前者運營商沒有定義,「OP」是不是字母數字,而<op>=!===<=>=

我不相信有任何一個地方的所有斯卡拉的語法糖列出。

+2

您可能想要添加unary_!!等運營商被列在其他職位之一,因爲這看起來像這裏的問題最詳盡的答案:) – Calum 2009-09-28 09:29:00

+1

...你已經做到了,謝謝! – Calum 2009-09-30 18:46:17

+1

什麼是'identifier_ ='?從來沒有見過。 – 2012-07-17 12:08:59

3

它們在Scala語言規範中定義。 據我所知,你所提到的只有三個「魔術」功能。

Scalas getter和setter也可能涉及到你的「魔法」:

scala> class Magic { 
|  private var x :Int = _ 
|  override def toString = "Magic(%d)".format(x) 
|  def member = x 
|  def member_=(m :Int){ x = m } 
| } 

defined class Magic 

scala> val m = new Magic 

m: Magic = Magic(0) 

scala> m.member 

res14: Int = 0 

scala> m.member = 100 

scala> m 

res15: Magic = Magic(100) 

scala> m.member += 99 

scala> m 

res17: Magic = Magic(199) 
+0

如果你可以挖我的證據對這一索賠,你會回答我的問題;-)我以爲這將是在規格,但找到它們並不是一件有趣的工作。 – 2009-09-27 12:55:34

+2

Scala的語言規範: 6.15分配 ... 如果x是 一些模板中定義的參數的函數,並且在同一模板包含setter函數X_ =作爲成員, 則分配對象x = E被解釋爲調用函數x_ =(e)該設置器 函數。類似地,賦值爲無參數函數x的賦值f。x = e被解釋爲調用f。x _ =(e)。 在「=」運算符 左側具有函數應用的賦值f(args)= e被解釋爲f .update(args,e),即調用由f定義的更新函數 。 – Eastsun 2009-09-27 13:25:33

+0

I ment,證明沒有更多。 – 2009-09-28 22:11:13

15

除了updateapply,也有一些一元運算符它(我相信)的資格爲神奇:

  • unary_+
  • unary_-
  • unary_!
  • unary_~

添加到常規綴/後綴運營商(可以是幾乎任何東西),你也得爲自己的完整的軟件包。

你真的應該看看Scala語言規範。它是這方面唯一的權威來源。閱讀起來並不難(只要你對上下文無關文法感興趣),並且非常容易搜索。它唯一沒有明確指出的是XML支持。

10

對不起,如果它不完全回答你的問題,但我最喜歡的WTF時刻到目前爲@模式匹配內的賦值運算符。感謝「Scala編程」的軟拷貝,我發現它非常快。

使用@我們可以將模式的任何部分綁定到變量,如果模式匹配成功,變量將捕獲子模式的值。下面是從編程Scala中的例子中(第15.2節 - 變量綁定):

expr match { 
    case UnOp("abs", e @ UnOp("abs", _)) => e 
    case _ => 
} 

如果整個圖案匹配成功, 則該匹配 UnOp的部分( 「ABS」,_)部分作爲變量e提供 。

而且here的什麼編程斯卡拉說一下吧。

+0

您可以與我們分享@操作員的作用嗎? – 2009-09-28 21:59:33

+0

是的,只是編輯我的答案:-) – Yardena 2009-10-01 20:27:29

2

我也模式匹配上的參數任意號碼添加_*

case x: A(_*) 

而且運營商關聯規則,從Odersky的-勺凡納斯書:

Scala中的運算符的關聯性由其最後的 字符決定。如< ...>所述,任何以':'結尾 的方法都會在其右操作數上調用,並傳入 左操作數。以任何其他字符結尾的方法都是其他方式。他們在左邊的操作數上被調用,傳入右邊的操作數 。所以a * b產生a *(b),但a :: b產生b.:::(a)。


也許我們還應該提到的句法脫糖爲可發現here


和表達(當然!),用於對

a -> b //converted to (a, b), where a and b are instances 
替代語法

(正如po inted出來,這個人是剛剛經歷了圖書館做了一個隱式轉換,所以它可能不符合條件的,但我覺得這對新人共同的益智遊戲)


+1

IIRC' - >'只是一個庫函數。 – 2012-10-23 18:29:14

2

我想補充一點,還有一個「神奇」的特質 - scala.Dynamic

一個啓用動態調用的標記特徵。對於任意方法名稱meth和參數列表args以及對於任意字段名稱的字段訪問x.field,此特徵的實例x允許方法調用x.meth(args)field

如果呼叫沒有原生x支持(即,如果類型檢查失敗),則根據下面的規則改寫爲:

foo.method("blah")  ~~> foo.applyDynamic("method")("blah") 
foo.method(x = "blah") ~~> foo.applyDynamicNamed("method")(("x", "blah")) 
foo.method(x = 1, 2) ~~> foo.applyDynamicNamed("method")(("x", 1), ("", 2)) 
foo.field   ~~> foo.selectDynamic("field") 
foo.varia = 10  ~~> foo.updateDynamic("varia")(10) 
foo.arr(10) = 13 ~~> foo.selectDynamic("arr").update(10, 13) 
foo.arr(10)   ~~> foo.applyDynamic("arr")(10) 

作爲Scala的2.10的,定義該性狀的直接或間接子類只有在啓用了語言功能動態的情況下才有可能。

所以你可以做的東西一樣

import scala.language.dynamics 

object Dyn extends Dynamic { 
    def applyDynamic(name: String)(a1: Int, a2: String) { 
    println("Invoked " + name + " on (" + a1 + "," + a2 + ")"); 
    } 
} 

Dyn.foo(3, "x"); 
Dyn.bar(3, "y"); 
+0

該鏈接無法正常工作。你能更新嗎? – Jus12 2014-10-16 07:42:21