在Scala中使用def或var声明函数
在Scala中声明函数时,我试图找出在Scala中使用def或var声明函数,scala,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> 然而,我能做到 g = f g: Int => Int = <function1> 问题3:这是否意味着(x:Int)
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>
然而,我能做到
g = f
g: Int => Int = <function1>
问题3:这是否意味着(x:Int)Int
与Int=>Int=
相同?如果是这样的话,我们是否应该在某些情况下偏袒其中一方
事情正在与(下划线)联系起来
scala>3(f)
res49:Int=6
scala>3(g 41;
:11:错误:类型不匹配;
找到:()=>Int=>Int
必需:Int=>Int
三(g)
^
问题4:为什么会发生这种情况?在Scala中,(下划线)的用法是什么
为什么会发生这种情况?我猜def映射到val
def
是一种方法(在JVM术语中),因此分配它没有意义
解析器随后会感到困惑,并最终试图通过将赋值f=g
解释为
val $ires6 = f
f = g
这两个语句都是非法的,因此会出现两个错误:
- 如果没有显式类型注释或
扩展,则无法将方法分配给val
——请参见下文)
- 您不能重新分配
val
(如果您想知道,$ires6
是REPL引入的新val
)
如果我在声明g中使用val而不是var,它们是等价的吗?如果没有,那有什么区别呢
不同之处在于,val
不能重新分配(即,它是一个常量引用),而var
可以重新分配(即,它是一个可变引用)
有关此主题的更多信息,请参见:
这是否意味着(x:Int)Int与Int=>Int=相同?如果是这样的话,我们是否应该在某些情况下偏袒其中一方
,尽管编译器会通过一个称为eta扩展的转换尽最大努力让您相信它们是。在某些情况下,这样的转换可以自动执行,而在另一些情况下,您需要显式执行,并使用尾部的\uuu
触发它
在您的特定示例中(传递预期函数的方法),可以自动执行扩展
你可以通过阅读来更深入地讨论喜欢哪种风格
为什么会发生这种情况?(下划线)在Scala中的用法是什么
下划线(\uu
),其中一个是我前面提到的,即触发方法到函数的eta扩展
这是方法的一种特殊语法,因此您无法将其应用于函数,因为这毫无意义
这就是为什么你可以做f
(这将把f
方法变成一个函数),但是你不能做g
(因为g
它已经是一个函数了)。可能重复的
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
^
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
scala> three(f _)
res49: Int = 6
scala> three(g _)
<console>:11: error: type mismatch;
found : () => Int => Int
required: Int => Int
three(g _)
^
val $ires6 = f
f = g