我试图找出在Scala中声明函数时def和之间的区别var/val.
假设我们有一个功能:
scala> def f(x: Int) = { x * 2 }
f: (x: Int)Int
Run Code Online (Sandbox Code Playgroud)
另一个功能g:
scala> var g = (x:Int) => x*2
g: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)
显然它们在以下方面是相同的:
scala> f(2)
res0: Int = 4
scala> g(2)
res1: Int = 4
Run Code Online (Sandbox Code Playgroud)
但是,我能做到
g = f
g: Int => Int = <function1>
Run Code Online (Sandbox Code Playgroud)
但不是
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
^
Run Code Online (Sandbox Code Playgroud)
问题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
Run Code Online (Sandbox Code Playgroud)
问题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 _)
^
Run Code Online (Sandbox Code Playgroud)
问题4:为什么会发生这种情况?_Scala 中(下划线)的用法是什么?
为什么会这样?我猜测def映射到val.
def 是一种方法(以JVM术语),因此分配它是没有意义的.
解析器是那么迷茫,它最终试图通过解释分配保存一天f = g为
val $ires6 = f
f = g
Run Code Online (Sandbox Code Playgroud)
这两个语句都是非法的,因此您会收到两个错误:
val没有显式类型注释或_扩展,则无法将方法分配给- 请参阅下文)val(如果你想知道,这$ires6是valREPL引入的新内容)如果我在声明g中使用val而不是var,它们是否相同?如果没有,那么有什么区别呢?
区别在于val不能重新分配(即它是一个常量引用),而varcan(即它是一个可变引用).
有关此主题的更多信息:Scala中var和val定义之间的区别是什么?
它是什么意思(x:Int)Int与Int => Int =?相同?如果是这样,是否有一些情况我们应该优先于另一方?
方法和函数不尽相同,尽管编译器通过称为eta-expansion的转换尽力让您相信它们.在某些情况下,这种转换可以自动执行,在某些其他情况下,您需要明确并通过尾随触发它_.
在您的特定示例中(传递期望函数的方法),可以自动执行扩展.
您可以阅读此Q/A,以便更深入地讨论更喜欢哪种风格.
为什么会这样?Scala中_(下划线)的用法是什么?
下划线(_)在scala中有很多用途,其中一个是我之前提到过的,即触发方法的eta扩展到函数中.
这是方法的特殊语法,因此您根本无法将其应用于函数,因为它没有任何意义.
这就是为什么你可以做f _(这将把f方法变成一个函数),但你做不到g _(因为g它已经是一个函数).
| 归档时间: |
|
| 查看次数: |
240 次 |
| 最近记录: |