2012-08-10 82 views
10

我是Scala的初级实践者,我看到了一些调用方法的不同语法。有些是不错的,因为忽略了无参数方法的括号,或者忽略了这个点,但有些真的让我困惑。例如:Scala - 方法调用语法

breakable { ... } 

这只是一个方法调用权吗?我也可以为多个参数或不是无参数函数的参数做到这一点吗?

感谢

+2

是的,这是一个封闭。你正在将一个代码块传递给一个方法。请注意,在Scala中,您可以使用{}代替(),将单个参数传递给方法 – aishwarya 2012-08-10 09:54:19

+0

这里有什么让您烦恼?它是方法名称之后的代码块('{...}')还是我们不用方法前缀对象/类名称的事实? – Nicolas 2012-08-10 09:55:33

回答

22

还有的调用方法两种标准方式:

obj.method(params) // dot notation 
obj method (params) // operator notation 

上面可以通过以下方式修改:

  1. 如果params是单个参数,则可以用{}代替()
  2. 如果params是单参数您正在使用操作符表示法,则可以删除括号。
  3. 如果method不带参数,则可以删除(params)(即删除空的())。
  4. 如果method:结尾,则它实际上以运算符绑定到正确的。也就是说,(params) method_: obj相当于obj.method_:(params)
  5. 无论哪种方式,只要标识符可以分开,空格是可选的。因此,可以在点符号上添加空格,例如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) 

如果:

  1. method被导入范围。
  2. 你保持括号(即使只有一个参数)

注意,有一个优先发布为好。如果你写obj method(params),即使它被导入到范围中,斯卡拉将假定method属于obj

+0

很棒的回答。我只是有一个关于你的点数1的问题,关于能够用{}符号而不是()来调用一个方法。这个语法有什么特定的原因吗?这个语法似乎在许多框架和他们记录的例子中经常使用。我想知道这个特定的语法是否支持一个非常具体的功能原因。它通常在将闭包作为参数传递给函数时使用?我想了解它的根源,以便我能够清楚地理解并推理它。谢谢。 – HiChews123 2016-08-12 03:33:37

+2

@ acspd7嗯,'()'和'{}'在_expression_中有不同的含义。也就是说,'2 *(3 + 4)'和'2 * {3 + 4}'具有相同的结果,但是不同的东西。只能将表达式放在括号内,而将_definitions_和_statements_放在大括号内,而最后一个语句的值是它的表达式值(大括号本身就是表达式)。 f(...)'可以用'f {...}替换的原因就是人们不必写'f({...})'。这允许人们编写看起来很原生的“用户”控制结构。 – 2016-08-12 22:29:54

15

如果我们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 

以上是令行禁止函数的例子