最近我对如何组织我的 Scala 代码感到困惑,因为有很多选择。
Scala 如何/何时使用包、对象、包对象来组织代码是否有任何指导方针?
首先,我们需要了解每种模块化策略的能力和局限性。
这些工作就像在 Java 中一样。您可以使用多个文件来声明一个包的不同部分,并且可以嵌套很多层。这为您的布局提供了最大的灵活性。然而,由于默认的类加载器只希望在包中找到类和接口,这就是 Scala 让你放在那里的全部。(类、特征和对象。)
对象可以包含任何东西——方法、字段、其他对象、类、特征等。子类、特征和对象实际上是它们自己的独立实体,包含对象作为名称损坏的前缀(就 JVM 而言)。一个对象必须完全包含在一个文件中,尽管您可以任意深度地嵌套子类,但这是通过修改越来越长的名称来完成的,而不是添加到类加载器的路径中。
只有对象和包的问题是您可能需要一个嵌套结构:
scala.xml
scala.xml.include
scala.xml.include.sax
所以你需要使用包(以避免拥有一个巨大的文件和令人不安的长类名)。但你也可能想要
import scala.xml._
使您可以使用各种常量和隐式转换,以便您需要使用对象。 包裹物品来救援;它们本质上与普通物体相同,但是当您说
import scala.xml._
您将获得包 ( scala.xml._
) 中的所有内容,以及相应包对象 ( scala.xml.package
) 中的所有内容。
现在我们知道每个部分是如何工作的,对于如何组织有相当明显的规则:
object
为。package object
除了包和对象之外,还有“隐含”可以帮助您构建代码。可以在这里找到一个很好的使用指南(避免误用):http: //suereth.blogspot.com/2011/02/slides-for-todays-nescala-talk.html
我还建议使用类型类来构建您的代码。这里有一篇关于这个主题的好文章:http: //debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html
我尽可能使用包,也就是说,当“模块”只是由类/特征/对象定义组成时。包的优点是可以直接从 Java 访问而没有奇怪的语法。
在所有其他情况下,我主要使用普通对象。
有时,我在项目包的根目录中的每个项目都有一个包对象。该包对象存储所有必要的隐式和最重要的类和对象。它允许对所有项目进行很好的单行导入。
如果您只对命名空间和将代码拆分为单独的文件感兴趣(听起来像 OP),请参阅@Rex 的答案。
如果您对模块系统有更多期望,例如可互换性或标准 ML 风格的仿函数,您可以使用此处描述的方法。
基本上,模块接口(也称为 SML 中的签名)成为 Scala 中的特征。模块(又名结构)是 Scala 中的对象。仿函数可以转换为类、抽象类,甚至是带有某些实现的特征,其中仿函数参数转换为抽象字段或构造函数参数,具体取决于您是否希望生成的模块具有兼容的类型。