我是Scala的初级实践者,我看到了一些调用方法的不同语法。有些是不错的,因为忽略了无参数方法的括号,或者忽略了这个点,但有些真的让我困惑。例如:Scala - 方法调用语法
breakable { ... }
这只是一个方法调用权吗?我也可以为多个参数或不是无参数函数的参数做到这一点吗?
感谢
我是Scala的初级实践者,我看到了一些调用方法的不同语法。有些是不错的,因为忽略了无参数方法的括号,或者忽略了这个点,但有些真的让我困惑。例如:Scala - 方法调用语法
breakable { ... }
这只是一个方法调用权吗?我也可以为多个参数或不是无参数函数的参数做到这一点吗?
感谢
还有的调用方法两种标准方式:
obj.method(params) // dot notation
obj method (params) // operator notation
上面可以通过以下方式修改:
params
是单个参数,则可以用{}
代替()
。params
是单参数和您正在使用操作符表示法,则可以删除括号。method
不带参数,则可以删除(params)
(即删除空的()
)。method
以:
结尾,则它实际上以运算符绑定到正确的。也就是说,(params) method_: obj
相当于obj.method_:(params)
。obj . method (params)
或在下一行写.method(params)
(如经常发生的调用链接),以及从操作符表示中删除空格,如a+b
中所示。还有一些元组推理的东西,但我尽量避免它,所以我不确定确切的规则。
但是,这些都不能解释您困惑的例子。在我解释它,但是,我想证明,也可用于调用方法的一些语法糖:
obj(params) // equivalent to obj.apply(params)
obj.x = y // equivalent to obj.x_=(y), if obj.x also exists
obj(x) = y // equivalent to obj.update(x, y)
obj op= y // equivalent to obj = obj op y, if op is symbolic
~obj // equivalent to obj.unary_~; also for !, + and -, but no other symbol
好了,现在你给的例子。一个可以进口稳定值的成员。 Java可以通过静态导入来实现静态方法,但是Scala具有更一般的机制:从包,对象或通用实例导入没有什么不同:它带来了类型成员和值成员。方法属于后一类。
所以,想象你有val a = 2
,你做import a._
。这将涉及范围全部Int
方法,所以你可以直接打电话给他们。你不能这样做+(2)
,因为这会被解释为unary_+
一个电话,但你可以叫*(4)
,例如:
scala> val a = 2
a: Int = 2
scala> import a._
import a._
scala> *(4)
res16: Int = 8
现在,这里的规则。您可以拨打
method(params)
如果:
method
被导入范围。注意,有一个优先发布为好。如果你写obj method(params)
,即使它被导入到范围中,斯卡拉将假定method
属于obj
。
很棒的回答。我只是有一个关于你的点数1的问题,关于能够用{}符号而不是()来调用一个方法。这个语法有什么特定的原因吗?这个语法似乎在许多框架和他们记录的例子中经常使用。我想知道这个特定的语法是否支持一个非常具体的功能原因。它通常在将闭包作为参数传递给函数时使用?我想了解它的根源,以便我能够清楚地理解并推理它。谢谢。 – HiChews123 2016-08-12 03:33:37
@ acspd7嗯,'()'和'{}'在_expression_中有不同的含义。也就是说,'2 *(3 + 4)'和'2 * {3 + 4}'具有相同的结果,但是不同的东西。只能将表达式放在括号内,而将_definitions_和_statements_放在大括号内,而最后一个语句的值是它的表达式值(大括号本身就是表达式)。 f(...)'可以用'f {...}替换的原因就是人们不必写'f({...})'。这允许人们编写看起来很原生的“用户”控制结构。 – 2016-08-12 22:29:54
如果我们desugar这一点,我们将有:
breakable({ ... })
此相匹配的签名
breakable: (op: ⇒ Unit): Unit
和使用如此命名的call-by-名参数(你也许会想这个作为通过一段代码作为参数)
更多在斯卡拉允许你这样写:
scala> def foo (op1: => Unit)(op2: => Unit) = {op1;op2;}
foo: (op1: => Unit)(op2: => Unit)Unit
scala> foo { println(1) } { println(2) }
1
2
以上是令行禁止函数的例子
是的,这是一个封闭。你正在将一个代码块传递给一个方法。请注意,在Scala中,您可以使用{}代替(),将单个参数传递给方法 – aishwarya 2012-08-10 09:54:19
这里有什么让您烦恼?它是方法名称之后的代码块('{...}')还是我们不用方法前缀对象/类名称的事实? – Nicolas 2012-08-10 09:55:33