繁体   English   中英

在Scala中使用def或var声明函数

[英]Declare a function using def or var in Scala

我试图找出在Scala中声明函数时defvar/val之间的区别。

说我们有一个功能:

scala> def f(x: Int) = { x * 2 }
f: (x: Int)Int

还有另一个函数g:

scala> var g = (x:Int) => x*2
g: Int => Int = <function1>

显然,它们在以下方面是相同的:

scala> f(2)
res0: Int = 4

scala> g(2)
res1: Int = 4

但是我可以

g = f
g: Int => Int = <function1>

但不是

scala> f = g
<console>:13: error: missing arguments for method f;
follow this method with `_' if you want to treat it as a partially applied function
val $ires6 = f
             ^
<console>:10: error: reassignment to val
       f = g
         ^

问题1 :为什么会这样? 我猜想def映射到val

问题2 :如果在声明g中使用val而不是var ,它们是否等效? 如果没有,那有什么区别?

然后,我尝试:

scala> def three( timetwo:(Int) => Int ) = { timetwo(3) } 
three: (timetwo: Int => Int)Int

scala> three(g)
res47: Int = 6

scala> three(f)
res48: Int = 6

问题3(x: Int)Int等于Int => Int = <function1>吗? 如果是这样,是否存在某些情况下我们应该偏爱另一个?

事物之间用_ (下划线)连接,

scala> three(f _)
res49: Int = 6

scala> three(g _)
<console>:11: error: type mismatch;
found   : () => Int => Int
required: Int => Int
          three(g _)
                ^

问题4 :为什么会这样? Scala中_ (下划线)的用途是什么?

为什么会这样? 我猜想def映射到val。

def是一种方法(使用JVM术语),因此分配它没有任何意义。

然后,解析器感到困惑,并最终通过将赋值f = g解释为

val $ires6 = f
f = g

这两个语句都是非法的,因此会出现两个错误:

  • 您不能在没有显式类型注释或_扩展的情况下将方法分配给val参见下文)
  • 你不能重新分配val (如果你想知道, $ires6是一个新鲜的val由REPL介绍)

如果在声明g中使用val而不是var,它们是否等效? 如果没有,那有什么区别?

区别在于val无法重新分配(即,它是一个常量引用),而var可以重新分配(即,它是可变引用)。

有关此主题的更多信息: Scala中的var和val定义之间有什么区别?

是(x:Int)Int等于Int => Int =吗? 如果是这样,是否存在某些情况下我们应该偏爱另一个?

方法和函数并不相同 ,尽管编译器会通过称为eta-expansion的转换尽最大努力使您相信它们。 在某些情况下,这种转换可以自动执行,而在另一些情况下,您需要明确并用尾随_触发。

在您的特定示例中(通过需要功能的方法),可以自动执行扩展。

您可以阅读本问答 ,以更深入地讨论首选哪种样式。

为什么会这样? _(下划线)在Scala中有什么用?

下划线( _在scala中有许多用途 ,其中一个是我之前提到的用途 ,即触发方法将eta扩展为函数。

这是方法的一种特殊语法,因此您根本无法将其应用于函数,因为这没有任何意义。

这就是为什么可以执行f _ (它将把f方法转换为函数),但是却不能执行g _ (因为g已经是一个函数)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM