Scala的“魔法”功能列表

时间:2009-09-27 09:50:40

标签: syntax scala

我在哪里可以找到Scala的“魔术”功能列表,例如applyunapplyupdate+=等?

魔术函数我指的是编译器的一些语法糖使用的函数,例如

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

我搜索了scala magicfunctions的同义词的某种组合,但我没有找到任何内容。

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

6 个答案:

答案 0 :(得分:77)

据我所知:

Getters / setters相关:

apply
update
identifier_=

模式匹配:

unapply
unapplySeq

有关-推导:

map
flatMap
filter
withFilter
foreach

前缀运算符:

unary_+
unary_-
unary_!
unary_~

除此之外,任何隐含的从A到B. Scala也会将A <op>= B转换为A = A <op> B,如果前一个运算符未定义,则“op”不是字母数字,{{1} }不是<op>=!===<=

我不相信有任何一个地方可以列出所有Scala的语法糖。

答案 1 :(得分:16)

除了updateapply之外,还有一些一元运算符(我相信)有资格作为魔法:

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

添加常规的中缀/后缀运算符(几乎可以是任何东西),你就可以得到完整的包。

你真的应该看一下Scala语言规范。它是这个东西的唯一权威来源。它并不难读(只要你对无上下文语法感到满意),并且很容易搜索。唯一没有说明的是XML支持。

答案 2 :(得分:11)

很抱歉,如果它没有完全回答你的问题,但到目前为止,我最喜欢的WTF时刻是@作为模式匹配中的赋值运算符。感谢“Scala编程”的软拷贝,我发现它非常快。

使用@我们可以将模式的任何部分绑定到变量,如果模式匹配成功,变量将捕获子模式的值。以下是 Scala编程(第15.2节 - 变量绑定)中的示例:

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

如果整个模式匹配成功,   然后匹配的部分   UnOp(“abs”,_)部分可用   作为变量e。

here编程Scala 所说的。

该链接不再有效。 Here就是那个。

答案 3 :(得分: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)

答案 4 :(得分:3)

我还会为模式匹配添加_*

case x: A(_*)

运营商关联性规则,来自Odersky-Spoon-Venners的书:

  

Scala中运算符的关联性由其最后一个决定   字符。如在&lt; ...&gt;中提到的,任何结束的方法   在一个':'字符中调用它的右操作数,传入   左操作数。以任何其他字符结尾的方法是另一种   四处走走。它们在左操作数上调用,传入   右操作数。所以a * b产生一个。*(b),但是::: b产生b。:::( a)。


也许我们也应该提到 for expressions 的语法贬义,可以找到here


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

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

(正确指出,这只是一个通过库完成的隐式转换,所以它可能没有资格,但我觉得这对新手来说是一个普遍的益智者)


答案 5 :(得分:3)

我想补充说还有一个“神奇”的特质 - scala.Dynamic

  

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

     

如果field本身不支持某个呼叫(即如果类型检查失败),则会根据以下规则重写:

x
     

从Scala 2.10开始,只有在启用语言特征动态时,才能定义此特征的直接或间接子类。

所以你可以做像

这样的事情
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)