class - 为什么 Scala 包对象中的类不受欢迎?

标签 class scala object package deprecated

从 2.10 开始,-Xlint提示在包对象内部定义的类。但为什么?在包对象中定义一个类应该与在一个单独的包中定义具有相同名称的类完全相同,除了方便得多。

在我看来,Scala 的严重设计缺陷之一是无法将类实体(例如变量声明、函数定义)以外的任何内容放在文件的顶层。相反,您被迫将它们放入一个单独的“包对象”(通常在 package.scala 中),与它们所属的其余代码分开,并违反基本编程规则,即概念上相关的代码应该 body 上也有关系。我看不出为什么 Scala 在概念上不能在顶层允许它在较低级别允许的任何东西,并且任何非类的东西都会自动放入包对象中,这样用户就不必担心它了。

例如,在我的情况下,我有一个 util包,在它下面我有许多子包( util.ioutil.textutil.timeutil.osutil.mathutil.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) = ...

  // ...
  // ...
}

如果没有这个,我将不得不根据乐趣与类而不是语义来不方便地拆分代码。我想,另一种选择是将它们放在一个普通的对象中——有点违背了首先拥有包装对象的目的。

最佳答案

But why? Defining a class inside a package object should be exactly equivalent to defining the classes inside of a separate package with the same name,



恰恰。语义(当前)是相同的,因此如果您喜欢在包对象中定义一个类,那么应该有充分的理由。但现实情况是,至少有一个很好的理由不(继续阅读)。

except a lot more convenient



怎样更方便?
如果你这样做:
package object mypkg {
  class MyClass
}

您也可以执行以下操作:
package mypkg {
  class MyClass
}

您甚至可以在此过程中保存一些字符 :)

现在,不要过度使用包对象的一个​​很好且具体的理由是,当包打开时,包对象是 不是 .
一个常见的场景是让您的代码在多个项目之间分派(dispatch),每个项目在同一个包中定义类。这里没问题。
另一方面,一个包对象(像任何对象一样)是封闭的(正如规范所说的“每个包只能有一个包对象”)。换句话说,
您将只能在 中定义包对象一个 你的项目。
如果你试图在两个不同的项目中为同一个包定义一个包对象,就会发生不好的事情,因为你最终会得到两个
同一 JVM 类的不同版本(在我们的例子中,您最终会得到两个“mypkg.class”文件)。
根据具体情况,您最终可能会导致编译器提示它找不到您在包对象的第一个版本中定义的内容,
或出现“错误的符号引用”错误,甚至可能出现运行时错误。这是包对象的一般限制,因此您必须注意它。
在包对象中定义类的情况下,解决方案很简单:不要这样做(与仅将类定义为顶级相比,您不会获得任何实质性的东西)。
对于类型别名、vals 和 vars,我们没有这么奢侈,所以在这种情况下,需要权衡一下语法便利(与在对象中定义它们相比)是否值得,然后注意不要定义重复的包对象。

关于class - 为什么 Scala 包对象中的类不受欢迎?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17270003/

相关文章:

scala - 为什么可变映射在 Spark 中的 UserDefinedAggregateFunction(UDAF) 中自动变为不可变

json - JScript JSON 对象检查

javascript - 定义数组对象属性

java - super() 方法有什么作用?

r - Rcpp 中如何判断 SEXP 中存储的对象的类?

2.11 中的 Scala 脚本

scala - 在 Intellij 中运行简单的 Scala

php - 在类中加载 config.php

c# - 将整数转换为对象并返回会导致 InvalidCastException

swift - 从同一类中的结构调用方法