斯卡拉的“魔术”function列表
我在哪里可以find一个斯卡拉的“魔术”function,如apply
,不apply
, update
, +=
等列表?
例如,magic-functions是指编译器的某些语法糖所使用的函数
o.update(x,y) <=> o(x) = y
我GOOGLE了一些scala
magic
和functions
同义词的组合,但是我没有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>=
不是!=
, ==
, <=
或>=
。
我不相信有任何一个地方,所有的斯卡拉语法糖列出。
除了update
和apply
,还有一些(我相信)符合神秘的一元运算符:
-
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");