Urb*_*ond 35 scala class object package deprecated
从2.10开始,-Xlint
抱怨在包对象中定义的类.但为什么?在包对象中定义一个类应该完全等同于在具有相同名称的单独包中定义类,除了更方便.
在我看来,Scala中一个严重的设计缺陷是无法在文件的顶层放置除类类实体之外的任何东西(例如变量声明,函数定义).相反,您被迫将它们放入一个单独的"包对象"(通常在package.scala
)中,与它们所属的其余代码分开并违反基本的编程规则,即概念上相关的代码应该是物理相关的同样.我没有看到任何理由为什么Scala在概念上不允许在较低级别允许的任何顶层级别,并且任何类非类似的东西都会自动放入包对象中,这样用户就不必担心它.
例如,在我的情况下,我有一个util
包,并在其下我有一个号码的子包(util.io
,util.text
,util.time
,util.os
,util.math
,util.distances
,等等),该组的在语义上相关的函数,类,有时变量异质集合.我目前将所有各种函数,类等存储package object
在目录中名为io.scala
或等的文件text.scala
中util
.这很好用,因为函数和类可以混合的方式非常方便,例如我可以做类似的事情:
package object math {
// Coordinates on a sphere
case class SphereCoord(lat: Double, long: Double) { ... }
// great-circle distance between two points
def spheredist(a: SphereCoord, b: SphereCoord) = ...
// Area of rectangle running along latitude/longitude lines
def rectArea(topleft: SphereCoord, botright: SphereCoord) = ...
// ...
// ...
// Exact-decimal functions
class DecimalInexactError extends Exception
// Format floating point value in decimal, error if can't do exactly
formatDecimalExactly(val num: Double) = ...
// ...
// ...
}
Run Code Online (Sandbox Code Playgroud)
如果没有这个,我将不得不根据乐趣与类而不是语义分解代码.我认为,替代方案是将它们放在一个普通的对象中 - 首先要破坏包装对象的目的.
Rég*_*les 28
但为什么?在包对象中定义一个类应该完全等同于在具有相同名称的单独包中定义类,
正是.语义(目前)是相同的,所以如果你喜欢在包对象中定义一个类,那么应该有一个很好的理由.但实际情况是,至少有一个很好的理由(继续阅读).
除了更方便
怎么那更方便?如果你这样做:
package object mypkg {
class MyClass
}
Run Code Online (Sandbox Code Playgroud)
您也可以执行以下操作:
package mypkg {
class MyClass
}
Run Code Online (Sandbox Code Playgroud)
你甚至可以在这个过程中保存几个字符:)
现在,一个很好的和具体的理由不与包对象走极端的是,虽然包是开放的,包对象都没有.一个常见的场景是将代码分派到多个项目中,每个项目在同一个包中定义类.这里没问题.另一方面,一个包对象(就像任何对象一样)被关闭(正如规范所说的那样"每个包只能有一个包对象").换句话说,您只能在一个中定义包对象你的项目.如果你试图在两个不同的项目中为同一个包定义一个包对象,那么就会发生不好的事情,因为你最终会得到同一个JVM类的两个不同版本(在我们的例子中你最终会得到两个"mypkg").类"文件".根据具体情况,编译器可能会抱怨它无法找到您在包对象的第一个版本中定义的内容,或者出现"错误的符号引用"错误,甚至可能出现运行时错误.这是包对象的一般限制,因此您必须了解它.在在包对象中定义类的情况下,解决方案很简单:不要这样做(假设与仅将类定义为顶级相比,您将不会获得任何实质性的东西).对于类型别名,vals和vars,我们不要