“模块化” Scala 指南

发布于 2024-11-26 12:57:00 字数 84 浏览 6 评论 0 原文

最近我对如何组织我的 Scala 代码感到困惑,因为有很多选择。

Scala 是否有关于如何/何时使用包、对象、包对象来组织代码的指南?

Recently I've become confused how to organize my Scala code, because there are a lot of options.

Are there any guidelines for Scala how/when to use packages, objects, package objects for organizing code?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

顾北清歌寒 2024-12-03 12:57:00

了解 Scala 的功能

首先,我们需要了解每种模块化策略的功能和局限性。

这些工作方式与 Java 中一样。您可以使用多个文件来声明一个包的不同部分,并且可以深度嵌套多个级别。这为您的布局提供了最大的灵活性。然而,由于默认的类加载器只希望在包中查找类和接口,因此 Scala 只允许您将这些内容放在那里。 (类、特征和对象。)

对象

对象可以包含任何东西——方法、字段、其他对象、类、特征等。子类、特征和对象实际上是它们自己独立的实体,以包含对象作为名称 -损坏的前缀(就 JVM 而言)。一个对象必须完全包含在一个文件中,尽管您可以任意深度地嵌套子类,但这是通过修改越来越长的名称来完成的,而不是添加到类加载器的路径中。

包对象

仅拥有对象和包的问题是您可能需要一种嵌套结构:

scala.xml
scala.xml.include
scala.xml.include.sax

因此您需要使用包(以避免拥有一个巨大的文件和令人不安的长类名)。但您可能还希望

import scala.xml._

提供各种常量和隐式转换,因此您需要使用对象。 包对象来救援;它们本质上与普通对象相同,但是当您说

import scala.xml._

您既获得了包中的所有内容 (scala.xml._),也获得了相应包对象 (scala.xml._) 中的所有内容。包)。

如何模块化代码

现在我们知道了每个部分的工作原理,对于如何组织有相当明显的规则:

  • 将相关代码放入包中
  • 如果有许多相关的子部分,请将它们放入子包中
  • 如果包需要隐式或常量,将它们放入该包的包对象中
  • 如果您的包层次结构有一个终端分支,则您可以选择它是对象还是包对象。有一些事情不允许包对象做(尽管列表一直在变小——我不确定除了禁止隐藏包中的其他名称之外还剩下什么),所以常规对象可能会是一个更好的选择。只要您不担心二进制兼容性,以后就很容易改变主意 - 在大多数情况下只需将 object 更改为 package object 即可。

Understanding Scala's capabilities

First, we need to understand the capabilities and limitations of each modularization strategy.

Packages

These work just like in Java. You can use many files to declare different parts of one package, and you can nest many levels deep. This provides maximum flexibility with your layout. However, since the default classloaders expect to only find classes and interfaces in packages, that's all Scala lets you put there. (Classes, traits, and objects.)

Objects

Objects can contain anything--methods, fields, other objects, classes, traits, etc.. Subclasses, traits, and objects are actually their own separate entities with the containing object as a name-mangled prefix (as far as the JVM is concerned). An object must be contained wholly within one file, and although you can nest subclasses arbitrarily deep, it's done via mangling increasingly long names, not adding to the path for the classloader.

Package objects

The problem with only having objects and packages is that you might want a nested structure:

scala.xml
scala.xml.include
scala.xml.include.sax

so that you need to use packages (to avoid having one gigantic file and disturbingly long class names). But you also might want

import scala.xml._

to make various constants and implicit conversions available to you, so that you need to use an object. Package objects come to the rescue; they are essentially the same as ordinary objects, but when you say

import scala.xml._

you get both everything in the package (scala.xml._) but also everything in the corresponding package object (scala.xml.package).

How to modularize your code

Now that we know how each part works, there are fairly obvious rules for how to organize:

  • Place related code into a package
  • If there are many related sub-parts, place those into sub-packages
  • If a package requires implicits or constants, put those into the package object for that package
  • If you have a terminal branch of your package hierarchy, it is your choice as to whether it should be an object or a package object. There are a few things that package objects are not allowed to do (though the list is getting smaller all the time--I'm not sure there's anything left except a prohibition against shadowing other names in the package), so a regular object might be a better choice. As long as you're not worried about binary compatibility, it's easy to change your mind later--just change object to package object in most cases.
黯淡〆 2024-12-03 12:57:00

除了包和对象之外,还有“隐式”可以帮助您构建代码。可以在这里找到一个很好的使用指南(避免误用):
http://suereth.blogspot.com/2011/02 /slides-for-todays-nescala-talk.html

我还建议使用类型类来构建代码。关于这个主题有一篇很好的文章: http:// debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html

Besides packages and objects there are 'implicits' which help you structuring your code. A nice guideline for using (avoid misuse) can be found here:
http://suereth.blogspot.com/2011/02/slides-for-todays-nescala-talk.html

I would also suggest type classes to structure your code. Here a nice write up on this topic: http://debasishg.blogspot.com/2010/07/refactoring-into-scala-type-classes.html

挽容 2024-12-03 12:57:00

我尽可能使用包,也就是说,当“模块”仅由类/特征/对象定义组成时。包的优点是可以直接从 Java 访问,无需奇怪的语法。

在所有其他情况下,我主要使用普通对象。

有时,我在项目包的根目录中为每个项目都有一个包对象。该包对象存储所有必要的隐式以及最重要的类和对象。它允许对所有项目进行良好的单行导入。

I use packages whenever I can, that is to say, when the "module" is just made of class/traits/object definitions. Packages have the advantage of being directly accessible from Java without weird syntax.

In all other case, I use mostly plain objects.

Sometimes, I have one package object per project in the root of the project package. That package object stores all the necessary implicits and most important class and objects. It allows a nice single-line import for all the project.

孤寂小茶 2024-12-03 12:57:00

如果您只对命名空间和将代码拆分为单独的文件感兴趣(听起来像OP),请参阅@Rex的答案。

如果您对模块系统有更多期望,例如可互换性或标准 M​​L 风格函子,则可以使用 此处

基本上,模块接口(又名 SML 中的签名)成为 Scala 中的特征。模块(又名结构)是 Scala 中的对象。函子可以转换为类、抽象类,甚至可以通过某些实现将函子参数转换为抽象字段或构造函数参数,具体取决于您是否希望生成的模块具有兼容的类型。

If you are only interested in namespacing and splitting code into separate files (as it sounds like the OP is) see @Rex's answer.

If you expect more from a module system, such as interchangeability or Standard ML-style functors, you can use the approach described here.

Basically, module interfaces (aka signatures in SML) become traits in Scala. Modules (aka structures) are objects in Scala. Functors can be translated to either classes, abstract classes, or even traits with some implementation with functor arguments converted to abstract fields or constructor arguments, depending on whether you want the resulting modules to have compatible types or not.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文