2009-09-27 163 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