阅读Scala 中大括号和圆括号之间的正式区别是什么,什么时候应该使用它们?,我还是不知道怎么理解包裹在{}.
考虑以下两个 REPL 会话:
@ val f = { (x: Int) =>
x
val y = x
y
}
f: Int => Int = ammonite.$sess.cmd30$$$Lambda$1765/0x0000000801346840@24c7b944
Run Code Online (Sandbox Code Playgroud)
@ { (x: Int) =>
x
val y = x
y
}
cmd31.sc:3: not found: value x
val y = x
^
Compilation Failed
Run Code Online (Sandbox Code Playgroud)
我有几个问题。
{...}整体上是一个函数值。在第二个片段中,只有(x: Int) => \n x部分是函数值(对不起\n,表示换行)。为什么?{ (x: Int) => \n ... },它什么时候被解释为函数值,什么时候不是?{}) 是函数值的一部分,还是只有(...) => ...函数值在里面?如果是它的一部分,表格有名字吗?例如,我认为(_ + _)可以称为函数值的占位符语法。更新:这纯粹是一个 Ammonite 问题。详情见答案。
这里的问题是菊石。
Scala REPL 有一个粘贴模式,允许您在计算之前粘贴多行:
:paste
sealed trait X
class Implementation extends X // impossible without doing it at once
// Ctrl+D
Run Code Online (Sandbox Code Playgroud)
Ammonite 没有这样的粘贴模式,但它允许您执行多行复制粘贴...但将它们全部包装在Ammonite 中{},这样 Ammonite 就会展开。所以你的代码:
{ (x: Int) =>
x
val y = x
y
}
Run Code Online (Sandbox Code Playgroud)
被编译器视为
(x: Int) =>
x // end of function definition
val y = x // new variable calling x, which isn't defined anywhere
y // call to undefined y, because previous line failed
Run Code Online (Sandbox Code Playgroud)
第一个示例之所以有效,是因为val f = 菊石的解析器无法假设所有代码都在一个块内,因此在将其传递给编译器之前它不会将其剥离。
正如文档所建议的,如果您不希望出现这种行为,您应该添加另一层大括号:
{{ (x: Int) =>
x
val y = x
y
}}
Run Code Online (Sandbox Code Playgroud)
这不是编译器和语言规范问题,而是某些特定 REPL 实现的问题。
| 归档时间: |
|
| 查看次数: |
34 次 |
| 最近记录: |