为什么值方法不能在宏外使用?
Why value method cannot be used outside macros?
错误信息
`value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting.
val x = version.value
^
明确指出如何解决问题,例如,使用 :=
val x = settingKey[String]("")
x := version.value
sbt uses macros heavily中的解释说明
The value
method itself is in fact a macro, one that if you invoke it
outside of the context of another macro, will result in a compile time
error, the exact error message being...
And you can see why, since sbt settings are entirely declarative, you
can’t access the value of a task from the key, it doesn’t make sense
to do that.
但是我很困惑声明性 sbt 的性质是什么意思。例如,直觉上我会认为以下 vanilla Scala 片段在语义上类似于 sbt 的
def version: String = ???
lazy val x = s"Hello $version" // ok
trait Foo {
def version: String
val x = version // ok
}
因为这是合法的,显然 Scala 片段在语义上与 sbt 片段不等同。我想知道是否有人可以详细说明为什么 value
不能在宏之外使用?是纯粹与宏语法相关的句法原因还是我遗漏了一些关于 sbt 本质的基本知识?
另外一句话说
Defining sbt’s task engine is done by giving sbt a series of settings, each setting declaring a task implementation. sbt then executes those settings in order. Tasks can be declared multiple times by multiple settings, the last one to execute wins.
所以在
行的那一刻
val x = version.value
将被执行(如果允许的话!),整个程序仍在设置中,SBT 不知道 version
.
的最终定义
In what sense is the program "still being set up"?
SBT 的行动顺序基本上是(可能遗漏了一些东西):
- 您所有的 Scala 构建代码都是 运行。
- 它包含一些设置和任务定义,SBT 在遇到时收集这些(以及来自核心、插件等的)
- 它们按拓扑排序到任务图中,去重("the last one to execute wins")等
- 设置已评估。
- 现在您实际上可以 运行 执行任务(例如从 SBT 控制台)。
version.value
仅在步骤 4 后可用,但 val x = version.value
运行 在步骤 1 后可用。
Would not lazy evaluation take care of that?
嗯,当你写 val x = ...
时,就没有惰性求值。但是 lazy val x = ...
运行 也在第 1 步。
错误信息
`value` can only be used within a task or setting macro, such as :=, +=, ++=, Def.task, or Def.setting.
val x = version.value
^
明确指出如何解决问题,例如,使用 :=
val x = settingKey[String]("")
x := version.value
sbt uses macros heavily中的解释说明
The
value
method itself is in fact a macro, one that if you invoke it outside of the context of another macro, will result in a compile time error, the exact error message being... And you can see why, since sbt settings are entirely declarative, you can’t access the value of a task from the key, it doesn’t make sense to do that.
但是我很困惑声明性 sbt 的性质是什么意思。例如,直觉上我会认为以下 vanilla Scala 片段在语义上类似于 sbt 的
def version: String = ???
lazy val x = s"Hello $version" // ok
trait Foo {
def version: String
val x = version // ok
}
因为这是合法的,显然 Scala 片段在语义上与 sbt 片段不等同。我想知道是否有人可以详细说明为什么 value
不能在宏之外使用?是纯粹与宏语法相关的句法原因还是我遗漏了一些关于 sbt 本质的基本知识?
另外一句话说
Defining sbt’s task engine is done by giving sbt a series of settings, each setting declaring a task implementation. sbt then executes those settings in order. Tasks can be declared multiple times by multiple settings, the last one to execute wins.
所以在
行的那一刻val x = version.value
将被执行(如果允许的话!),整个程序仍在设置中,SBT 不知道 version
.
In what sense is the program "still being set up"?
SBT 的行动顺序基本上是(可能遗漏了一些东西):
- 您所有的 Scala 构建代码都是 运行。
- 它包含一些设置和任务定义,SBT 在遇到时收集这些(以及来自核心、插件等的)
- 它们按拓扑排序到任务图中,去重("the last one to execute wins")等
- 设置已评估。
- 现在您实际上可以 运行 执行任务(例如从 SBT 控制台)。
version.value
仅在步骤 4 后可用,但 val x = version.value
运行 在步骤 1 后可用。
Would not lazy evaluation take care of that?
嗯,当你写 val x = ...
时,就没有惰性求值。但是 lazy val x = ...
运行 也在第 1 步。