他在scala编程中的书(第5章第5.9节第93页)
奥德斯基提到了这个表达“bills !*&^%~ code!
”
在同一页的脚注中:
“到现在为止,你应该能够弄清楚,鉴于此代码,Scala编译器将
调用(bills.!*&^%~(code)).!()."
这对我来说有点神秘,有人可以解释这里发生了什么吗?
答案 0 :(得分:9)
奥德斯基的意思是说有可能拥有这样的有效代码。例如,下面的代码:
class BadCode(whose: String, source: String) {
def ! = println(whose+", what the hell do you mean by '"+source+"'???")
}
class Programmer(who: String) {
def !*&^%~(source: String) = new BadCode(who, source)
}
val bills = new Programmer("Bill")
val code = "def !*&^%~(source: String) = new BadCode(who, source)"
bills !*&^%~ code!
只需将其复制并粘贴到REPL上即可。
答案 1 :(得分:3)
对于调用采用单个参数的方法或具有空参数列表的方法,句点是可选的。
使用此功能时,假定方法名称后面的空格后面的下一个块是单个参数。
因此,
(!票据*安培; ^%〜(代码))。!()
与
相同账单!*& ^%〜代码!
第二个感叹号调用第一个方法调用返回值的方法。
答案 2 :(得分:2)
我不确定这本书是否提供了方法签名,但我认为它只是对Scala的语法糖的评论,所以它假定你键入:
bill add monkey
其中有一个对象bill,它有一个带有参数的方法add,然后它自动将其解释为:
bill.add(monkey)
作为一个小Scala生锈,我不完全确定它如何拆分代码!进入(代码)。!()除了模糊的灰色细胞痒!运算符用于触发一个actor,它在编译器术语中可能被解释为对象的隐式。!()方法。
答案 3 :(得分:2)
'。()'与方法调用是可选的组合(如上所述Wysawyg)和使用(几乎)任何你喜欢的字符命名方法的能力,使得在Scala中编写看起来像的方法成为可能运算符重载。你甚至可以创建自己的运营商。
例如,我有一个处理3D计算机图形的程序。我有自己的班级Vector
来表示3D矢量:
class Vector(val x: Double, val y: Double, val z: Double) {
def +(v: Vector) = new Vector(x + v.x, y + v.y, z + v.z)
// ...etc.
}
我还定义了一个方法**
(上面未显示)来计算两个向量的cross product。在Scala中创建自己的运算符非常方便,没有多少其他编程语言具有这种灵活性。