当你用 Seq(1,2,3) 创建一个 Seq 对象时会发生什么? [英] What happens when you create a Seq object with Seq(1,2,3)?

查看:46
本文介绍了当你用 Seq(1,2,3) 创建一个 Seq 对象时会发生什么?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当你对表达式求值时到底发生了什么:Seq(1,2,3)?

What exactly happens when you evaluate expression: Seq(1,2,3)?

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

I am new to Scala and I am now a bit confused about various collection types. Seq is a trait, right? So when you call it like that Seq(1,2,3) it must be some kind of a companion object? Or not? Is it some kind of a class that extends Seq? And most importantly what is the type of the returned value? Is it Seq and if yes, why is not explicitly the extension class instead?

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

Also in REPL I see that the contents of the evaluated expression is actually a List(1,2,3), but the type is apparently Seq[Int]. Why is not an Indexed collection type, like Vector? What is the logic behind all that?

推荐答案

当你对表达式求值时到底发生了什么:Seq(1,2,3)?

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

In Scala, foo(bar) is syntactic sugar for foo.apply(bar), unless this also has a method named foo, in which case it is a method call on the implicit this receiver, i.e. just like Java, it is then equivalent to this.foo(bar).

就像任何其他面向对象语言一样,方法调用的接收者单独决定如何处理该调用,因此在这种情况下,Seq 决定要做什么.

Just like any other OO language, the receiver of a method call alone decides what to do with that call, so in this case, Seq decides what to do.

Seq 是一种特质,对吧?

Seq is a trait, right?

标准库中有两个Seq:

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

So when you call it like that Seq(1,2,3) it must be some kind of a companion object? Or not?

是的,它必须是一个对象,因为你只能在对象上调用方法.你不能在类型上调用方法,因此,当你看到一个方法调用时,它必须是一个对象.总是.因此,在这种情况下,Seq 不可能Seq trait,它必须是 Seq 对象.

Yes, it must be an object, since you can only call methods on objects. You cannot call methods on types, therefore, when you see a method call, it must be an object. Always. So, in this case, Seq cannot possibly be the Seq trait, it must be the Seq object.

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

Note that "it must be some kind of a companion object" is not true. The only thing you can see from that piece of code is that Seq is an object. You cannot know from that piece of code whether it is a companion object. For that, you would have to look at the source code. In this particular case, it turns out that it is, in fact, a companion object, but you cannot conclude that from the code you showed.

是某种扩展 Seq 的类吗?

Is it some kind of a class that extends Seq?

没有.它不可能是一个类,因为你只能在对象上调用方法,而类在 Scala 中不是对象.(这不像 Ruby 或 Smalltalk,其中类也是 Class 类的对象和实例.)它必须是一个对象.

No. It cannot possibly be a class, since you can only call methods on objects, and classes are not objects in Scala. (This is not like Ruby or Smalltalk, where classes are also objects and instances of the Class class.) It must be an object.

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

And most importantly what is the type of the returned value?

最简单的方法是查看 Seq.apply 的文档:

The easiest way to find that out is to simply look at the documentation for Seq.apply:

  • A:集合元素的类型
  • elems:创建的集合的元素
  • 返回一个包含元素 elems 的新集合

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

Creates a collection with the specified elements.

  • A: the type of the collection's elements
  • elems: the elements of the created collection
  • returns a new collection with elements elems

所以,如你所见,Seq.apply 的返回类型是 Seq,或者更准确地说,Seq[A],其中 A 是一个类型变量,表示集合元素的类型.

So, as you can see, the return type of Seq.apply is Seq, or more precisely, Seq[A], where A is a type variable denoting the type of the elements of the collection.

它是 Seq 吗?如果是,为什么不是明确的扩展类?

Is it Seq and if yes, why is not explicitly the extension class instead?

因为没有扩展类.

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

Also, the standard design pattern in Scala is that the apply method of a companion object returns an instance of the companion class or trait. It would be weird and surprising to break this convention.

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

Also in REPL I see that the contents of the evaluated expression is actually a List(1,2,3), but the type is apparently Seq[Int].

静态类型Seq[Int].这就是您需要知道的全部内容.这就是你可以知道的全部.

The static type is Seq[Int]. That is all you need to know. That is all you can know.

现在,Seq是一个trait,并且traits不能被实例化,所以运行时类型将是Seq的一些子类.但!您不能也不必关心它是什么特定的运行时类型.

Now, Seq is a trait, and traits cannot be instantiated, so the runtime type will be some subclass of Seq. But! You cannot and must not care, what specific runtime type it is.

为什么不是索引集合类型,如 Vector?这一切背后的逻辑是什么?

Why is not an Indexed collection type, like Vector? What is the logic behind all that?

你怎么知道下次调用它时它不会返回Vector?一点都不重要,因为静态类型是 Seq ,因此您只能在其上调用 Seq 方法,并且您只能依赖Seq 的契约,即 Seq 的后置条件、不变量等.即使你知道返回的是一个Vector,你也无法利用这些知识做任何事情.

How do you know it is not going to return a Vector the next time you call it? It wouldn't matter one bit, since the static type is Seq and thus you are only allowed to call Seq methods on it, and you are only allowed to rely on the contract of Seq, i.e. Seq's post-conditions, invariants, etc. anyway. Even if you knew it was a Vector that is returned, you wouldn't be able to do anything with this knowledge.

因此,Seq.apply 返回它可能返回的最简单的东西,那就是一个 List.

Thus, Seq.apply returns the simplest thing it can possibly return, and that is a List.

这篇关于当你用 Seq(1,2,3) 创建一个 Seq 对象时会发生什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆