【问题标题】:why declaration of methods in different style different results in scala为什么在scala中以不同样式声明方法会产生不同的结果
【发布时间】:2015-10-31 11:43:20
【问题描述】:

以下是两种以不同样式声明的方法。两者都在做同样的工作。我想知道为什么

  1. 检查函数类型需要不同的语法(黄色 块)
  2. 调用函数需要不同的语法(绿色块)
  3. scala repl 上两种方法的声明给出了不同的结果 (红块)

另外,请建议,哪种方式是首选的声明方式 方法或这两种风格是否有任何特殊用例 方法声明?


编辑 1:

以下是截图中的命令:-

Welcome to Scala version 2.11.7 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_79).
Type in expressions to have them evaluated.
Type :help for more information.

scala> def add(x:Int, y :Int): Int = {x+y}
add: (x: Int, y: Int)Int

scala> def sum = (x:Int, y:Int) => {x+y}
sum: (Int, Int) => Int

scala> :t add
<console>:12: error: missing arguments for method add;
follow this method with `_' if you want to treat it as a partially applied function
       add
       ^

scala> :t add(_, _)
(Int, Int) => Int

scala> :t sum
(Int, Int) => Int

scala> add
<console>:12: error: missing arguments for method add;
follow this method with `_' if you want to treat it as a partially applied function
       add
       ^

scala> add(_, _)
res1: (Int, Int) => Int = <function2>

scala> sum
res2: (Int, Int) => Int = <function2>

编辑 2:

@Shadowlands

我在dzone 上读到过,其中指出“当需要一个函数但提供了一个方法时,它将自动转换为一个函数。这称为 ETA 扩展。”。

现在,如果 ETA 小心地将您的方法转换为函数。是否真的需要使用 sum 样式,因为它看起来像 Function 对象的额外开销。

【问题讨论】:

标签: function scala methods types call


【解决方案1】:

简单地说,add 是一个函数,它接受两个 Int 参数并返回一个 Int 结果,而 sum 是一个 0 参数函数,它返回一个新函数,而该函数又接受两个 @ 987654326@ 参数并返回Int 结果。事实上,sum 可以很容易地定义为:

def sum = add _

至于如何定义你的函数,这取决于它是如何使用的。通常,大部分时间使用add 样式,因为它更易于理解和使用。但是,如果您要将函数作为参数传递给另一个函数,那么 sum 样式的表述会更方便,并且可以传达更多关于预期如何使用该函数的意图。

【讨论】:

  • 我读过dzone.com/articles/revealing-scala-magician%E2%80%99s,“当一个函数被期望但提供了一个方法时,它会自动转换为一个函数。这被称为ETA扩展。”。现在,如果 ETA 小心地将您的方法转换为函数。是否真的需要使用 sum 样式,因为它看起来像 Function 对象的额外开销。
  • @rits 不,这当然不是必需的!有时它可能很有用,例如,您希望如何使用它的指示符,或者您可能正在定义一个隐式值,然后作为隐式参数自动传递给适当类型的函数。
  • @rits 嗯,cmets 并不真正适用于整个多行示例,所以我会尝试一些简短的(而且相当做作)。想象一个定义为def operate(x:Int, y :Int)(implicit op: (Int, Int) =&gt; Int): Int = op(x, y) 的方法。然后你可以设置你的代码来读取一个标志并使用它来决定你想要使用哪个操作,例如:implicit val op = if (flag) add _ else someOtherOp _,然后当你调用operate(x,y)时,该方法将执行你之前选择的隐式操作。跨度>
  • 到目前为止,我还不知道隐式关键字的概念。可能,在了解了这个关键字之后,我就能理解你的例子了。如果无法理解,我将在 stackoverflow 上提出一个新问题 :)
【解决方案2】:

这就是 REPL 的实现方式。您键入的代码包含在object 中。因此,您的def add 成为此对象的方法,而def sum 是返回Function 的方法。当您像这样寻址add 时:add(_, _) 您正在寻址方法,而当您将sum 寻址为sum 时,您正在寻址 sum 执行的结果,即函数。

方法和函数之间的差异描述here

PS。尝试检查sum _的类型

【讨论】:

  • "尝试检查 sum _ 的类型"。这条线真的帮助我理解了这个概念。支持你的答案。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 2021-11-10
  • 1970-01-01
相关资源
最近更新 更多