If statement SBT TaskKey If语句
我用的是SBT 0.13。我遇到了一个问题,如下玩具示例所示:If statement SBT TaskKey If语句,if-statement,sbt,If Statement,Sbt,我用的是SBT 0.13。我遇到了一个问题,如下玩具示例所示: lazy val nativeOne = TaskKey[Unit]( "nativeOne", "One" ) lazy val nativeTwo = TaskKey[Unit]( "nativeTwo", "Two" ) lazy val testProj = Project( id = "testProj", base = file( "." ), settings = Defaults.defau
lazy val nativeOne = TaskKey[Unit]( "nativeOne", "One" )
lazy val nativeTwo = TaskKey[Unit]( "nativeTwo", "Two" )
lazy val testProj = Project(
id = "testProj",
base = file( "." ),
settings = Defaults.defaultSettings ++ Seq(
scalaVersion := "2.10.2",
nativeOne :=
{
println( "Native one"
},
nativeTwo :=
{
if ( true )
{
println( "Native two" )
}
else
{
val n1 = nativeOne.value
}
}
)
)
如果我进入sbt并运行nativeTwo
:
> nativeTwo
Native one
Native two
为什么会这样?为什么要评估false
分支?不允许在TaskKey中进行分支吗?在sbt中,所有依赖项都是在任务运行之前并行计算的。如果你要构建一个你所拥有的图表,它将是:
nativeOne
^
|
nativeTwo
你要做的是安排任务。在sbt中,我们尝试促进返回其他任务直接使用的结果的任务,因此使用.value
。这不是直接运行任务,而是说“给我其他任务的结果”
理解sbt语法的最好方法是模仿scala异步项目。您的代码类似于以下异步代码:
nativeOne = async {
println( "Native one")
}
nativeTwo = async {
if(true) println("Native Two")
else await(nativeOne)
}
在这里,更明显的是,您只是说“如果尚未计算,请等待值”
如果您想选择性地执行任务,则需要在sbt的任务[\u]
层执行,这一层更为详细。我们使用的是“动态任务”。它选择在运行时实际运行哪些任务
因此,您需要使用Def.taskDyn
方法,该方法允许您按照定义的顺序组合任务。您将使用TaskKey
s的toTask
方法处理任务本身。这不是处理任务生成的值。下面是一个示例build.sbt
:
val taskOne = taskKey[Int]("test")
val taskTwo = taskKey[Int]("test2")
val taskThree = taskKey[Int]("test3")
val switchEm = settingKey[Boolean]("switch 'em")
switchEm := true
taskOne := { println("taskOne"); 1 }
taskTwo := { println("taskTwo"); 2 }
taskThree := Def.taskDyn({
if(switchEm.value) taskTwo.toTask
else taskOne.toTask
}).value
然后在sbt控制台中:
> reload
[info] Loading project definition from /home/jsuereth/projects/sbt/test-projects/project
[info] Set current project to test-projects (in build file:/home/jsuereth/projects/sbt/test-projects/)
> taskThree
2
另外请注意,您不会在inspect命令中看到已更正的依赖项,因为这些依赖项是动态添加的:
>检查任务三
[信息]任务:Int
[信息]说明:
[信息]测试3
[信息]提供人:
[info]{file:/home/jsuereth/projects/sbt/test projects/}test projects/*:tasktree
[信息]定义于:
[info]/home/jsuereth/projects/sbt/testprojects/build.sbt:15
[信息]依赖项:
[信息]*:switchEm
[info]*:在sbt中设置数据在任务运行之前,所有依赖项都是并行计算的。如果要构建一个您拥有的图形,它将是:
nativeOne
^
|
nativeTwo
您试图做的是对任务进行排序。在sbt中,我们尝试提升返回其他任务直接使用的结果的任务,从而得到.value
。这样做的目的不是直接运行任务,而是说“给我其他任务的结果”
理解sbt语法的最佳方法是模仿scala异步项目。您的代码类似于以下异步代码:
nativeOne = async {
println( "Native one")
}
nativeTwo = async {
if(true) println("Native Two")
else await(nativeOne)
}
在这里,更明显的是,您只是说“如果尚未计算,请等待值”
如果您希望选择性地执行任务,则需要在sbt的Task[\u]
层执行,这一层更为详细。我们使用的是“动态任务”。它选择在运行时实际运行哪些任务
因此,您需要使用Def.taskDyn
方法,该方法允许您按照定义的顺序组合任务。您将使用TaskKey
s的toTask
方法处理任务本身。这不是在处理任务产生的值。下面是一个示例build.sbt
:
val taskOne = taskKey[Int]("test")
val taskTwo = taskKey[Int]("test2")
val taskThree = taskKey[Int]("test3")
val switchEm = settingKey[Boolean]("switch 'em")
switchEm := true
taskOne := { println("taskOne"); 1 }
taskTwo := { println("taskTwo"); 2 }
taskThree := Def.taskDyn({
if(switchEm.value) taskTwo.toTask
else taskOne.toTask
}).value
然后在sbt控制台中:
> reload
[info] Loading project definition from /home/jsuereth/projects/sbt/test-projects/project
[info] Set current project to test-projects (in build file:/home/jsuereth/projects/sbt/test-projects/)
> taskThree
2
另外请注意,您不会在inspect命令中看到已更正的依赖项,因为这些依赖项是动态添加的:
>检查任务三
[信息]任务:Int
[信息]说明:
[信息]测试3
[信息]提供人:
[info]{file:/home/jsuereth/projects/sbt/test projects/}test projects/*:tasktree
[信息]定义于:
[info]/home/jsuereth/projects/sbt/testprojects/build.sbt:15
[信息]依赖项:
[信息]*:switchEm
[info]*:settingsData我想这是因为有一种宏魔法(在编译时)可以发现nativeOne.value的访问并添加任务依赖项。在一般情况下,宏无法知道计算if的哪个路径,因此它必须始终添加依赖项。那么解决方案是什么?您可以动态(在运行时)将节点添加到生成图中。有一个咒语使用Def.taskDyn。这里有一个与此相关的例子:我认为这是因为有一种宏魔法(在编译时)可以发现nativeOne.value的访问,并添加一个任务依赖项。在一般情况下,宏无法知道计算if的哪个路径,因此它必须始终添加依赖项。那么解决方案是什么?您可以动态(在运行时)将节点添加到生成图中。有一个咒语使用Def.taskDyn。这里有一个切向相关的示例: