【发布时间】:2011-09-30 10:22:42
【问题描述】:
有一天,我想学习 Scala。我从喜欢这种语言的人那里看到了非常令人鼓舞的情况。
不过,今天不是那一天。今天,我只想对团队的构建文件进行一些更改。不幸的是,这个构建文件是与 SBT 放在一起的,几乎无法理解。
我的主要问题是,在我看来,SBT 引入了一些巨大的新运算符集合,这些运算符使用字符串和列表来创建某种 sbt 对象。例如,在 sbt 中:
"args4j" % "args4j" % "2.0.12"
显然是实际定义的;但是,我什至无法在scala repl 中分辨出它是什么类型,因为在 repl 中我得到了明显的错误:
scala> val tstcrap = "args4j" % "args4j" % "2.0.12"
<console>:6: error: value % is not a member of java.lang.String
val tstcrap = "args4j" % "args4j" % "2.0.12"
即使在设置类路径以包含sbt-launch.jar 文件并执行import sbt._ 之后,我也会收到此错误。
同样,我正在处理这样的事情:
val jarSources = (descendents(classesOutput ##, "*") ---
assemblyExclude(classesOutput ##))
## 运算符是什么,--- 在做什么,更重要的是这个表达式的类型是什么?所有这些新操作符是否都记录在某处,是否有某种方法可以获得使用与 sbt 构建文件中使用的语言相同的语言的 scala repl?
看着这个sbt 文件让我想起了试图破译perl 而没有阅读任何相关手册页的情况。 (不推荐的活动)
更新:查看下面答案中的链接,并查看标记为 sbt 的其他问题和答案后,我发现了我缺少的主要 scala 知识: scala 允许定义在方法被解析之前将被调用的隐式转换。在这种情况下,sbt 在 ManagedProject 特征内定义了从 String 到私有类 sbt.GroupID 的隐式转换,因此
"a" % "b"
真的有点像
(new GroupID("a")) % "b"
我想关于隐式转换的解析顺序和其他规则一定会变得非常复杂;它几乎让我想起了在 C++ 中通过非成员函数完成运算符重载时可能引入的噩梦。
【问题讨论】:
-
其实隐式规则和作用域规则没什么不同——你定义什么,同一个包里有什么,你导入了什么,一个类中定义了什么,这个类继承了什么,就像作用域一样.除此之外,伴生对象为静态类型,伴生对象为预期类型,伴生对象为类型参数。 SBT 不是“你好,世界”。给定 SBT 教程,可以轻松编写配置。然而,了解如何 SBT 的工作原理并不比了解 Maven、Gradle、Ivy、Ant 或 Buildr 的工作原理更容易。
-
顺便说明一下SBT是什么版本的。 SBT 到 0.7.7 是一回事,但从最近发布的 0.10.0 开始的 SBT 可能会有很大不同。
-
三减号的
mimimi而不是---看起来更像是一个方法名而不是一个运算符,但并不更加清晰。隐式转换并不遥远 - 在实际文件中或在导入的文件中,几乎与super.mimimi (...)一样容易找到。 -
运算符重载又回来了:(