斯卡拉的“魔术”function列表

我在哪里可以find一个斯卡拉的“魔术”function,如apply ,不applyupdate+=等列表?

例如,magic-functions是指编译器的某些语法糖所使用的函数

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

我GOOGLE了一些scala magicfunctions同义词的组合,但是我没有find任何东西。

我对标准库中魔术函数的使用不感兴趣,但是其中存在魔术函数。

我所知道的:

相关的获得者/设置者:

 apply update identifier_= 

模式匹配:

 unapply unapplySeq 

对于-内涵:

 map flatMap filter withFilter foreach 

前缀运算符:

 unary_+ unary_- unary_! unary_~ 

除此之外,任何从A到B的隐含。如果未定义前一个操作符,“op”不是字母数字,并且<op>= A = A <op> B ,则Scala也会将A <op>= B转换为A = A <op> B <op>=不是!===<=>=

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

除了updateapply ,还有一些(我相信)符合神秘的一元运算符:

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

再加上定期的中缀/后缀运算符(几乎可以是任何东西),并且你已经得到了完整的包。

你真的应该看看Scala语言规范。 这是这个东西唯一的权威来源。 阅读起来并不困难(只要你熟悉上下文无关的语法),并且非常容易search。 它唯一没有明确指出的是XML支持。

对不起,如果它不完全回答你的问题,但我最喜欢的WTF时刻迄今为@模式匹配内的赋值运算符。 感谢“Scala编程”的软拷贝,我发现它非常快。

使用@我们可以将模式的任何部分绑定到variables,如果模式匹配成功,variables将捕获子模式的值。 下面是来自Scala编程的例子(Section 15.2 – Variable Binding):

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

如果整个模式匹配成功,则匹配UnOp(“abs”,_)部分的部分可用作variablese。

这就是Scala编程所说的。

它们在Scala语言规范中定义。 据我所知,你提到的只有三个“魔术”function。

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) 

我还会在任意数量的参数上添加_*来进行模式匹配

 case x: A(_*) 

和Odersky-Spoon-Venners书中的操作员关联规则:

Scala中的运算符的关联性由其最后一个字符决定。 正如<…>所提到的,任何以':'结尾的方法在其右操作数上被调用,传入左操作数。 以其他方式结束的方法是相反的。 它们在左边的操作数上调用,传入右边的操作数。 所以a * b产生a *(b),但a :: b产生b.:::(a)。


也许我们也应该提到在这里可以find的expression式的句法parsing


和(当然!), 对的替代语法

 a -> b //converted to (a, b), where a and b are instances 

(正确地指出,这只是一个通过图书馆完成的隐式转换 ,所以它可能不符合条件,但是我觉得这是新手常见的困惑)


我想补充一点,还有一个“神奇”的特质 – scala.Dynamic

启用dynamic调用的标记特征。 此特征的实例x允许为任意方法名称方法调用x.meth(args)方法名称和参数列表args以及为任意字段名称field访问x.field field

如果一个调用本来不是由x支持的(例如,如果types检查失败),它将按照以下规则被重写:

 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开始,只有在启用了语言特征dynamic的情况下,才能定义此特征的直接或间接子类。

所以你可以做类似的东西

 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");