我在哪里可以找到Scala的“神奇”的功能列表,如apply
,unapply
,update
,+=
,等?
魔术函数是指编译器的某些语法糖使用的函数,例如
o.update(x,y) <=> o(x) = y
我用Google搜索了的scala
magic
和的某种组合functions
,但没有找到任何东西。
我对标准库中魔术函数的用法不感兴趣,但是其中存在魔术函数。
我在哪里可以找到Scala的“神奇”的功能列表,如apply
,unapply
,update
,+=
,等?
魔术函数是指编译器的某些语法糖使用的函数,例如
o.update(x,y) <=> o(x) = y
我用Google搜索了的scala
magic
和的某种组合functions
,但没有找到任何东西。
我对标准库中魔术函数的用法不感兴趣,但是其中存在魔术函数。
Answers:
我所知道的:
获得者/设定者相关:
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”是不是字母数字,而<op>=
不是!=
,==
,<=
或>=
。
而且我不相信在任何地方都可以列出Scala的所有语法糖。
identifier_=
啊 没看过。
object X { var _x = 0; def x_=(n: Int) { _x = n }; def x = _x }; X.x = 5; println(X.x)
identifier
这只是要成为一个占位符。得到它了。谢谢。
equals
一个被称为==
除了update
和之外apply
,还有一些一元运算符(我认为)是神奇的:
unary_+
unary_-
unary_!
unary_~
再加上常规的infix /后缀运算符(几乎可以是任何东西),您便拥有了完整的软件包。
您确实应该看一下Scala语言规范。它是此资料的唯一权威来源。阅读起来并不难(只要您对上下文无关的语法感到满意),并且非常容易搜索。唯一不能很好指定的是XML支持。
我还要补充_*
的模式匹配上的任意数目参数的像
case x: A(_*)
和操作员关联规则,摘自Odersky-Spoon-Venners的书:
Scala中运算符的关联性由其最后一个字符决定。如<...>所述,任何以':'字符结尾的方法都将在其右操作数上调用,并传入左操作数。以其他任何字符结尾的方法都是相反的。它们在其左操作数上调用,并传入右操作数。因此a * b产生a。*(b),但是a :: b产生b.:::(a)。
也许我们还应该提到的语法脱糖的表现可以发现这里
还有(当然!)对的替代语法
a -> b //converted to (a, b), where a and b are instances
(如正确指出的那样,这只是通过库进行的隐式转换,因此它可能不符合条件,但我发现它是新手的常见难题)
->
只是一个库函数。
我想补充一点,还有一个“魔术”特质- scala.Dynamic
:
启用动态调用的标记特征。
x
此特征的实例允许x.meth(args)
对任意方法名称meth
和参数列表进行方法调用,args
以及x.field
对任意字段名称进行字段访问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");
它们在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)