如何解释用花括号包裹的函数值(炸药问题)
How to interpret function value wrapped in curly braces (ammonite issue)
看了What is the formal difference in Scala between braces and parentheses, and when should they be used?,还是不懂{}
包裹的函数值怎么理解。
考虑以下两个 REPL 会话:
@ val f = { (x: Int) =>
x
val y = x
y
}
f: Int => Int = ammonite.$sess.cmd30$$$Lambda65/0x0000000801346840@24c7b944
@ { (x: Int) =>
x
val y = x
y
}
cmd31.sc:3: not found: value x
val y = x
^
Compilation Failed
我有几个问题。
- 为什么第一个片段可以编译而第二个片段不能?在第一个片段中,编译器知道
{...}
作为一个整体是一个函数值。在第二个片段中,只有 (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
Ammonite 没有这样的粘贴模式,但它 allows you to perform multi-line 复制粘贴...但是将它们全部包装在 {}
中,ammonite 会展开。所以你的代码:
{ (x: Int) =>
x
val y = x
y
}
被编译器视为
(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
第一个示例之所以有效,是因为您有 val f =
,所以 ammonite 的解析器无法假定 您的所有代码 都在一个块中,因此它不会在之前删除它将其传递给编译器。
正如文档所建议的那样,如果您不想要这种行为,您应该添加另一层大括号:
{{ (x: Int) =>
x
val y = x
y
}}
这不是编译器和语言规范问题,而是某些特定 REPL 实现的问题。
看了What is the formal difference in Scala between braces and parentheses, and when should they be used?,还是不懂{}
包裹的函数值怎么理解。
考虑以下两个 REPL 会话:
@ val f = { (x: Int) =>
x
val y = x
y
}
f: Int => Int = ammonite.$sess.cmd30$$$Lambda65/0x0000000801346840@24c7b944
@ { (x: Int) =>
x
val y = x
y
}
cmd31.sc:3: not found: value x
val y = x
^
Compilation Failed
我有几个问题。
- 为什么第一个片段可以编译而第二个片段不能?在第一个片段中,编译器知道
{...}
作为一个整体是一个函数值。在第二个片段中,只有(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
Ammonite 没有这样的粘贴模式,但它 allows you to perform multi-line 复制粘贴...但是将它们全部包装在 {}
中,ammonite 会展开。所以你的代码:
{ (x: Int) =>
x
val y = x
y
}
被编译器视为
(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
第一个示例之所以有效,是因为您有 val f =
,所以 ammonite 的解析器无法假定 您的所有代码 都在一个块中,因此它不会在之前删除它将其传递给编译器。
正如文档所建议的那样,如果您不想要这种行为,您应该添加另一层大括号:
{{ (x: Int) =>
x
val y = x
y
}}
这不是编译器和语言规范问题,而是某些特定 REPL 实现的问题。