<scala>范围委派如何在SBT中运作?

时间:2018-03-02 09:32:25

标签: scala sbt

我已阅读reference以了解范围授权如何在SBT中运作。

在上面的参考页面中,我摘录了练习D.

ThisBuild / scalacOptions += "-Ywarn-unused-import"

lazy val projD = (project in file("d"))
  .settings(
    test := {
      println((Compile / console / scalacOptions).value)
    },
    console / scalacOptions -= "-Ywarn-unused-import",
    Compile / scalacOptions := scalacOptions.value // added by sbt
  )
  

如果您运行projD / test,您会看到什么?

     

列表()

     

列表(-Ywarn-unused-import)

     

其他什么?

他们的推理是

  

答案是List(-Ywarn-unused-import)。规则2找到projD / Compile / Zero,规则3找到projD / Zero / console,规则4找到ThisBuild / Zero / Zero。规则1选择projD / Compile / Zero,因为它具有子项目轴projD,并且配置轴具有比任务轴更高的优先级。

到目前为止,我能理解为什么Compile / console / sclacOptions将作用于projD / Compile / zero / scalacOptions。这是因为与我们想知道的密钥(Compile / console / scalacOptions)相比,projD / Compile / zero的配置轴比projD / zero / console更具体。

  

接下来,Compile / scalacOptions引用scalacOptions.value,接下来我们需要找到projD / Zero / Zero的委托。规则4找到ThisBuild / Zero / Zero,因此它解析为List(-Ywarn-unused-import)。

在这里,我无法理解为什么ThisBuild / Zero / Zero赢得projD / Compile / Zero。因为我们想要找到的键的范围是projD / zero / zero,所以projD / Compile / zero与Thisbuild [遵循参考中的规则1]相比具有更具体的值。

我认为原因是Compile / scalacOptions具有scalacOptions.value的值,它生成递归定义。然后,我们可以使用projD / Zero / console。

1 个答案:

答案 0 :(得分:2)

我认为你对解释第二部分中对差异范围的引用感到有些困惑。让我们明确写下示例中的所有范围:

ThisBuild / Zero / Zero / scalacOptions += "-Ywarn-unused-import"

lazy val projD = (project in file("d"))
  .settings(
    test := { println((Compile / console / scalacOptions).value) }
  )

projD / Zero / console / scalacOptions -= "-Ywarn-unused-import"
projD / Compile / Zero / scalacOptions := (projD / Zero / Zero / scalacOptions).value

我必须取出这两个设置,才能引用projD,否则它的定义相同。

因此,从第一部分开始,您了解projD / Compile / Zero / scalacOptions胜过projD / Zero / console / scalacOptionsThisBuild / ...

现在让我们把它的价值用在我们的任务中。但它的价值是什么?它指的是未明确定义的projD / Zero / Zero / scalacOptions。所以我们需要为它找到一个代表。目前,我们尚未与projD / CompileprojD / console竞争,范围中唯一合适的密钥位于ThisBuild / Zero / Zero范围内。

我试着在这里说明一下(省略/ scalacOptions以节省空间):

projD     / Compile / console // the one we need in the task
projD     / Zero    / console // could be applied by rule 3, but looses to the next one:
projD     / Compile / Zero    // applies by rule 2 (task scope delegation), defined with next one:
projD     / Zero    / Zero    // not defined explicitly, so is delegated:
ThisBuild / Zero    / Zero    // applies by rule 4 (project scope delegation)