当您使用 Seq(1,2,3) 创建 Seq 对象时会发生什么?

2023-12-10

当您评估表达式时到底会发生什么:Seq(1,2,3)?

我是 Scala 新手,现在对各种集合类型有点困惑。Seq是一种特质,对吗?所以当你这样称呼它时:Seq(1,2,3),它一定是某种伴生对象吗?或不?它是某种扩展的类吗Seq?最重要的是,返回值的类型是什么?是吗Seq如果是,为什么不明确地使用扩展类?

同样在 REPL 中,我看到计算表达式的内容实际上是List(1,2,3),但类型显然是Seq[Int]。为什么它不是一个IndexedSeq集合类型,例如Vector?这一切背后的逻辑是什么?


当你计算表达式时到底会发生什么:Seq(1,2,3)?

在斯卡拉中,foo(bar)是语法糖foo.apply(bar), 除非this还有一个名为foo,在这种情况下,它是隐式方法调用this接收者,即就像Java一样,它相当于this.foo(bar).

就像任何其他 OO 语言一样,方法调用的接收者alone决定如何处理该调用,因此在这种情况下,Seq决定要做什么。

Seq 是一种特质,对吗?

那里有两个Seq标准库中的s:

  • The trait Seq,这是一个type.
  • The object Seq,这是一个value.

所以当你这样称呼它时Seq(1,2,3)它一定是某种伴生对象吗?或不?

是的,它必须是一个对象,因为您只能调用对象上的方法。您无法调用类型上的方法,因此,当您看到方法调用时,它must成为一个物体。总是。所以,在这种情况下,Seq 不可能 be the Seq特质,一定是Seq object.

请注意,“它必须是某种伴生对象”是不正确的。从那段代码中你唯一能看到的是Seq是一个对象。您无法从该代码段知道它是否是伴生对象。为此,您必须查看源代码。在这种特殊情况下,事实证明is,事实上,一个伴随对象,但您无法从您显示的代码中得出结论。

它是某种扩展 Seq 的类吗?

No. It 不可能是一个类,因为你只能调用对象的方法,而类不是 Scala 中的对象。 (这与 Ruby 或 Smalltalk 不同,其中类也是对象和实例Class类。)它must成为一个物体。

最重要的是返回值的类型是什么?

找出这一点的最简单方法就是简单地查看Seq.apply 的文档:

def apply[A](elems: A*): Seq[A]

创建具有指定元素的集合。

  • A:集合元素的类型
  • elems:创建的集合的元素
  • returns包含元素 elems 的新集合

所以,正如你所看到的,返回类型Seq.apply is Seq,或更准确地说,Seq[A], where A是一个类型变量,表示集合元素的类型。

是 Seq 吗?如果是,为什么不显式地使用扩展类?

因为没有扩展类。

此外,Scala 中的标准设计模式是apply伴生对象的方法返回伴生类或特征的实例。打破这个惯例将会是奇怪和令人惊讶的。

同样在 REPL 中,我看到计算表达式的内容实际上是一个 List(1,2,3),但类型显然是 Seq[Int]。

The 静态类型 is Seq[Int]。这就是您需要知道的全部。这就是你的全部can know.

Now, Seq is a trait,并且特征无法实例化,因此运行时类型将是某个子类Seq。但!您不能也不能关心它是什么特定的运行时类型。

为什么不是像 Vector 这样的 Indexed 集合类型?这一切背后的逻辑是什么?

你怎么知道它不会返回Vector下次你打电话的时候吗?这一点都不重要,因为静态类型是Seq因此你只能打电话Seq方法,并且您只能依赖于合同Seq, i.e. Seq无论如何,后置条件、不变量等等。甚至if你知道这是一个Vector返回后,您将无法利用这些知识做任何事情。

Thus, Seq.apply返回它可能返回的最简单的东西,那就是List.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

当您使用 Seq(1,2,3) 创建 Seq 对象时会发生什么? 的相关文章

随机推荐