加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

为什么Scala包对象中的类不同?

发布时间:2020-12-16 09:47:59 所属栏目:安全 来源:网络整理
导读:从2.10开始,-Xlint引用在包对象中定义的类。但为什么?在包对象中定义一个类应该完全等同于在一个具有相同名称的单独包中定义类,除了更方便之外。 在我看来,Scala中严重的设计缺陷之一是无法在文件的顶层放置类似实体(例如变量声明,函数定义)之外的任何
从2.10开始,-Xlint引用在包对象中定义的类。但为什么?在包对象中定义一个类应该完全等同于在一个具有相同名称的单独包中定义类,除了更方便之外。

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

例如,在我的case我有一个util包,在它下面我有一些子包(util.io,util.text,util.time,util.os,util.math,util.distances等)组的异质集合的函数,类和有时是语义相关的变量。我目前存储所有各种函数,类等在一个包对象坐在一个名为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
}

你甚至会在过程中保存几个字符:)

现在,一个良好和具体的原因,不要去打包对象是,虽然打包,包对象不是。一个常见的情况是在多个项目之间分配代码,每个项目在同一个包中定义类。这里没有问题。另一方面,包对象(像任何对象一样)被关闭(因为规范说“每个包只能有一个包对象”)。换一种说法,您将只能在其中一个项目中定义一个包对象。如果你试图在两个不同的项目中为同一个包定义一个包对象,会发生坏事,因为你将有效地结束两个不同版本的同一JVM类(在我们的情况下,你会得到两个“mypkg.class”文件)。根据情况,你可能最终与编译器抱怨,它不能找到您在包对象的第一个版本中定义的东西,或者获得“坏的符号引用”错误,或者潜在地甚至是运行时错误。这是包对象的一般限制,所以你必须知道它。在定义一个包对象内部的类的情况下,解决方案很简单:不要做它(假设你不会获得任何实质相比,只是将类定义为顶级)。对于类型aliase,vals和vars,我们没有这样一个luxuary,所以在这种情况下,是一个问题的权衡是否语法的方便(与定义它们在一个对象相比)是值得的,然后注意不要定义重复的包对象。

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读