阅读 Scala DSL 代码的最佳方法?
在 Squeryl 入门页面 上有一个 Scala 代码示例:
import sbt._
class Project(info: ProjectInfo) extends DefaultProject(info) {
val squeryl = "org.squeryl" % "squeryl_2.8.1" % "0.9.4-RC3"
}
我很困惑,因为 % 不是RichString 或 String 类中定义的方法。我最好的猜测是它在其他地方定义并称为隐式转换。
在 Scala 中阅读和理解此类代码的最佳方法是什么?
On Squeryl getting started page there is a Scala code sample:
import sbt._
class Project(info: ProjectInfo) extends DefaultProject(info) {
val squeryl = "org.squeryl" % "squeryl_2.8.1" % "0.9.4-RC3"
}
I'm puzzled because % is not a method defined in RichString or String classes. My best guess is that it's defined elsewhere and called as an implicit conversion.
What would be the best approach to read and understand such code in Scala?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
IntelliJ 的 Scala 插件通常可以为您找到它们,因此您可以使用 ^b 直接转到它。除此之外,它是从您导入的内容开始搜索文档。
IntelliJ's Scala plugin can normally find them for you, so you can use ^b to go right to it. Beyond that, it's a search through the documentation, starting with what you've imported.
这是隐式转换好吧!
与所有隐式函数一样,如果核心库中没有预定义它,那么最好的起点就是您的导入和导入。超类。
在给定的示例中,这显然是来自 SBT 的内容,因此您可以使用 在 Google 代码上快速搜索
It's an implicit conversion alright!
As with all implicits, if it isn't predefined in the core library, then the best place to start looking is your imports & superclass.
In the given example, this is pretty obviously something from SBT, so you can find it with a quick search on google code
它只能来自
import sbt._
或来自DefaultProject
。由于sbt
不是包对象,因此它必须来自DefaultProject
。这是因为隐式必须定义或导入到作用域中,并且只能从对象(
object
对象或类实例)导入它们。例外是在源或目标(如果已知)类型的伴生对象上隐式定义的,这两者都不适用,正如您已经检查的那样。不过,这有点没有意义。之所以创建新的Scaladoc,正是为了解决此类问题。
以 Scala 解析器为例:
~
方法未在Regex
上定义,因此我们搜索它。 此处查看最新的 scaladoc尝试下面的解释。最简单的方法:点击左上角的
#
,获取以符号开头的方法列表。向下滚动到~
,然后查看:BigInt OnceParser 解析器解析器。从现在开始,运用尝试、错误和直觉。有条不紊的方式:在搜索框中输入
JavaTokenParsers
快速找到该类,然后选择它。在方法列表中,找到从Regex
到其他内容的隐式
。只有一个,它需要Parser
。单击Parser
进行验证。您可能需要单击执行转换的方法
implicit def regex
,以查看它的定义位置:RegexParsers
。JavaTokenParsers
的文档显示了该方法的定义,即使该方法未在该类中定义或重写。这一点特别重要,因为如果您检查 SBT API 文档 在
DefaultProject
上,您会偶然发现它本身没有定义任何方法,并且仅提供 40 个方法的名称(如果我算的话)是的)祖先特征和阶级。单击ManagedProject
可能需要一段时间才能发现它具有从String
到GroupID
和RepositoryName
的隐式转换>,前者定义%
和%%
,后者定义at
。It can only come from
import sbt._
or fromDefaultProject
. Sincesbt
is not a package object, it must come fromDefaultProject
.This is because implicits must be defined or imported into the scope, and you can only import them from objects (either
object
objects, or instances of classes). The exception being implicits defined on companion objects of the source or target (when known) type, neither of which apply as you had already checked.That is a bit moot, though. The reason why the new Scaladoc was creates is precisely to handle such problems.
Take, for instance, a Scala parser:
The method
~
is not defined onRegex
, so we search for it. Check the latest scaladoc here to try out the explanation below.Simplest way: click on
#
in the upper left corner, to get a list of methods starting with a symbol. Scroll down to~
, and see: BigInt OnceParser Parser Parsers. From here on, use trial, error and intuition.Methodic way: type
JavaTokenParsers
on the search box to quickly find the class, then select it. On the list of methods, find animplicit
fromRegex
to something else. There's only one, which takes toParser
. Click onParser
to verify.You may want to click on
implicit def regex
, the method doing the conversion, to see where it is defined:RegexParsers
. The docs toJavaTokenParsers
show that method's definition even though it is not defined or overridden in that class.This is of particular importance, because if you check SBT API Documentation on
DefaultProject
, you'll stumble upon the fact that it defines no methods itself, and only provides the name of the methods on its 40 (if I counted it right) ancestor traits and classes. It can take a while until you click onManagedProject
to find it has implicit conversions fromString
to bothGroupID
andRepositoryName
, the former defining%
and%%
, while the later definesat
.