【问题标题】:How does Scala's type system compare to Java's? [closed]Scala 的类型系统与 Java 相比如何? [关闭]
【发布时间】:2014-12-13 22:43:51
【问题描述】:

在 Stack Overflow 的其中一个答案中引用了以下内容:

Scala 是一种完全面向对象的语言,比 Java 更重要,它是非研究语言上可用的最先进的类型系统之一。

Scala 的类型系统在哪些方面比 Java 更先进?

【问题讨论】:

  • 很抱歉,刚刚看到一个问题,要求 SO 用户比较 groovy scala 和 clojure,并获得 500 多票。我接受这个问题很广泛,但我不希望它被标记为不适合 SO
  • 感谢您的反对
  • Scala 的类型系统特性——除其他外——方差注释、路径依赖类型、高级类型、适当的存在类型、结构类型、抽象类型和单例类型。 Java 没有这些。
  • 好吧,在学习 Scala 时添加更多上下文,所以问题很广泛,但是您现在已经给了我一份清单,非常感谢
  • 我认为这是一个非常好的问题。它是客观的、相当具体的并且符合该网站的理念:一个以问答形式存储与编程相关的知识的数据库。答案比两段长,但这并没有让它变得不那么合适。

标签: java scala type-systems


【解决方案1】:

Scala 的类型系统几乎可以完成 Java 的所有功能(去除了一些缺陷,例如协变数组)。此外,它还具有以下特点:

差异注释

T 上泛型的抽象类C 可以成为C[U] 的子类型,其中UT 的子类型或超类型。

class C[+T] // C[T] <: C[U] iff T <: U
class D[-T] // C[T] <: C[U] iff U <: T

这在传递根据它们包含的值类型参数化的不可变数据结构时非常有用。例如,List[String]List[Any] 的子类型。

Java 为此使用通配符,从而将处理此问题的工作交给了 API 的用户,而不是定义者。在许多情况下,这不是最理想的。

依赖路径的类型

在 Java 中,非静态内部类类型的值存储指向包含类类型的对象的指针。在 Scala 中也是如此,除了它在类型系统中也以这种方式工作。例如:

class P {
  class C { }
}

val x = new P
val y = new P
var z = new x.C
z = new y.C // type error; x.C and y.C are distinct types

Java 缺少这个特性; xy 都有 P.C 类型。

高级类型

一个类型不仅可以在另一个类型上参数化,还可以在类型构造函数上:

trait Functor[F[_]] {
  def map[T, U](function: T => U)(functor: F[T]): F[U]
}

这在 FunctorMonad 等类型类中最有用。

Java 缺少此功能。

结构类型

如果一个类型包含结构类型的所有成员,则它是结构类型的子类型。

type S = { def x: String; def y: Int }

class A { def x = "a"; def y = 1 }
class B { def y = 1 }

这里,AS 的子类型,因为它定义了S 所需的def x: Stringdef y: IntB 不是S 的子类型,因为B 没有定义def y: Int。请注意,在许多情况下,在访问静态类型为结构类型的值的成员时会使用反射,因此通常不鼓励使用结构类型。

不过,它们可用于模拟 type lambdas,而无需运行时成本。

Java 缺少这个特性,而且它可以说不是很有用。

抽象类型

像方法一样,类型也可以是抽象的:

trait T {
  type G
  def f: G
}

class C extends T {
  override type G = Int
  override def f = 42
}

Java 缺少此功能。

单例类型

x 的单例类型包含 x 并且仅包含 x。这在想要保证方法返回this 时尤其有用:

trait T {
  def x: this.type
}

class C extends T {
  def x = this
}

val x: T = new C
x.x // has type x.type (which is a subtype of C), not type T

在 Java 中这是不可能的;您要么必须参数化 T 并依赖 CRTP,要么让 x 返回 T 而不是 C

底型

Scala 有底部类型Nothing,它是所有类型的子类型,不包含任何值。这是throw 表达式的类型和从不返回的函数的返回类型(即总是抛出异常或进入无限循环)。

Java 缺少此功能,而是使用void。 Scala 没有void,但明确区分不返回值的函数和不返回函数。

【讨论】:

    猜你喜欢
    • 2011-01-29
    • 1970-01-01
    • 1970-01-01
    • 2012-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-07
    • 1970-01-01
    相关资源
    最近更新 更多