[英]Declare a function using def or var in Scala
我试图找出在Scala中声明函数时def
和var/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.