使用 Seq(1,2,3) 创建 Seq 对象时会发生什么?
What happens when you create a Seq object with Seq(1,2,3)?
计算表达式时究竟发生了什么:Seq(1,2,3)
?
我是 Scala 的新手,现在对各种集合类型有点困惑。 Seq 是一种特质,对吧?所以当你这样称呼它时 Seq(1,2,3)
它一定是某种伴随对象?或不?它是某种扩展 Seq 的 class 吗?最重要的是返回值的类型是什么?是 Seq 吗?如果是,为什么不明确地使用扩展名 class?
同样在 REPL 中,我看到求值表达式的内容实际上是一个 List(1,2,3),但类型显然是 Seq[Int]。为什么不是像 Vector 这样的索引集合类型?这背后的逻辑是什么?
Seq
是 val
的:
package object scala {
...
val Seq = scala.collection.Seq
...
}
它指向对象 scala.collection.Seq
:
/** $factoryInfo
* The current default implementation of a $Coll is a `List`.
* @define coll sequence
* @define Coll `Seq`
*/
object Seq extends SeqFactory[Seq] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A]
}
并且当您执行 Seq(1,2,3)
时,apply()
方法从 scala.collection.generic.GenericCompanion
抽象 class:
中调用
/** A template class for companion objects of "regular" collection classes
* represent an unconstrained higher-kinded type. Typically
* such classes inherit from trait `GenericTraversableTemplate`.
* @tparam CC The type constructor representing the collection class.
* @see [[scala.collection.generic.GenericTraversableTemplate]]
* @author Martin Odersky
* @since 2.8
* @define coll collection
* @define Coll `CC`
*/
abstract class GenericCompanion[+CC[X] <: GenTraversable[X]] {
...
/** Creates a $coll with the specified elements.
* @tparam A the type of the ${coll}'s elements
* @param elems the elements of the created $coll
* @return a new $coll with elements `elems`
*/
def apply[A](elems: A*): CC[A] = {
if (elems.isEmpty) empty[A]
else {
val b = newBuilder[A]
b ++= elems
b.result()
}
}
}
最后,这个方法通过上面提到的代码构建了一个Seq
类型的对象
And most importantly what is the type of the returned value?
object MainClass {
def main(args: Array[String]): Unit = {
val isList = Seq(1,2,3).isInstanceOf[List[Int]]
println(isList)
}
}
打印:
true
所以,类型是scala.collection.immutable.List
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
的默认实现是List
。
Why is not an Indexed collection type, like Vector? What is the logic behind all that?
因为不可变的设计。该列表是不可变的,并使其不可变并具有恒定的前置操作,但 O(n) 追加操作成本和 O(n) 访问第 n 个元素的成本。 Vector
具有持续有效的访问和通过 id、前置和追加操作添加元素的实现。
要更好地了解 List 在 Scala 中的设计方式,请参阅 https://mauricio.github.io/2013/11/25/learning-scala-by-building-scala-lists.html
What exactly happens when you evaluate expression: Seq(1,2,3)
?
在 Scala 中,foo(bar)
是 foo.apply(bar)
的语法糖,除非 this
也有一个名为 foo
的方法,在这种情况下它是对隐式 this
接收者,即就像 Java,它等同于 this.foo(bar)
.
就像任何其他 OO 语言一样,方法调用的接收者 单独 决定如何处理该调用,因此在这种情况下,Seq
决定要做什么做。
Seq is a trait, right?
标准库中有两个Seq
:
trait Seq
,也就是类型。
object Seq
,这是一个值。
So when you call it like that Seq(1,2,3)
it must be some kind of a companion object? Or not?
是的,它必须是一个对象,因为您只能调用对象的方法。您不能在类型上调用方法,因此,当您看到方法调用时,它必须 是一个对象。总是。所以,在这种情况下,Seq
不可能是Seq
特征,它必须是Seq
对象。
请注意 "it must be some kind of a companion object" 不正确。从那段代码中您唯一可以看到的是 Seq
是一个对象。您无法从那段代码知道它是否是伴随对象。为此,您必须查看源代码。在这种特殊情况下,事实证明它 是 ,实际上是一个伴随对象,但您不能从您显示的代码中得出结论。
Is it some kind of a class that extends Seq?
没有。它 不可能 是 class,因为你只能调用对象的方法,而 classes 在 Scala 中不是对象。 (这不像 Ruby 或 Smalltalk,其中 classes 也是 Class
class 的对象和实例。)它 必须 是一个对象。
And most importantly what is the type of the returned value?
找出答案的最简单方法是简单地查看 the documentation for Seq.apply:
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
的 return 类型是 Seq
,或更准确地说,Seq[A]
,其中 A
是表示集合元素类型的类型变量。
Is it Seq and if yes, why is not explicitly the extension class instead?
因为没有扩展名class。
此外,Scala 中的标准设计模式是伴生对象的 apply
方法 return 是伴生对象 class 或特征的实例。打破这个约定会很奇怪和令人惊讶。
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]
。这就是您需要知道的全部内容。这就是您可以知道的全部内容。
现在,Seq
是一个 trait
,并且无法实例化特征,因此 运行时类型 将是 class 的某个子class Seq
。但!你不能也不应该关心它是什么特定的运行时类型。
Why is not an Indexed collection type, like Vector? What is the logic behind all that?
你怎么知道下次你调用它时它不会 return a Vector
?一点都不重要,因为静态类型是 Seq
因此你只能调用它的 Seq
方法,你只能依赖 [=17= 的契约],即 Seq
的 post-conditions,不变量等。即使 如果 你知道它是 Vector
returned,你将无法利用这些知识做任何事情。
因此,Seq.apply
return 可能是最简单的事情 return,那就是 List
。
计算表达式时究竟发生了什么:Seq(1,2,3)
?
我是 Scala 的新手,现在对各种集合类型有点困惑。 Seq 是一种特质,对吧?所以当你这样称呼它时 Seq(1,2,3)
它一定是某种伴随对象?或不?它是某种扩展 Seq 的 class 吗?最重要的是返回值的类型是什么?是 Seq 吗?如果是,为什么不明确地使用扩展名 class?
同样在 REPL 中,我看到求值表达式的内容实际上是一个 List(1,2,3),但类型显然是 Seq[Int]。为什么不是像 Vector 这样的索引集合类型?这背后的逻辑是什么?
Seq
是 val
的:
package object scala {
...
val Seq = scala.collection.Seq
...
}
它指向对象 scala.collection.Seq
:
/** $factoryInfo
* The current default implementation of a $Coll is a `List`.
* @define coll sequence
* @define Coll `Seq`
*/
object Seq extends SeqFactory[Seq] {
/** $genericCanBuildFromInfo */
implicit def canBuildFrom[A]: CanBuildFrom[Coll, A, Seq[A]] = ReusableCBF.asInstanceOf[GenericCanBuildFrom[A]]
def newBuilder[A]: Builder[A, Seq[A]] = immutable.Seq.newBuilder[A]
}
并且当您执行 Seq(1,2,3)
时,apply()
方法从 scala.collection.generic.GenericCompanion
抽象 class:
/** A template class for companion objects of "regular" collection classes
* represent an unconstrained higher-kinded type. Typically
* such classes inherit from trait `GenericTraversableTemplate`.
* @tparam CC The type constructor representing the collection class.
* @see [[scala.collection.generic.GenericTraversableTemplate]]
* @author Martin Odersky
* @since 2.8
* @define coll collection
* @define Coll `CC`
*/
abstract class GenericCompanion[+CC[X] <: GenTraversable[X]] {
...
/** Creates a $coll with the specified elements.
* @tparam A the type of the ${coll}'s elements
* @param elems the elements of the created $coll
* @return a new $coll with elements `elems`
*/
def apply[A](elems: A*): CC[A] = {
if (elems.isEmpty) empty[A]
else {
val b = newBuilder[A]
b ++= elems
b.result()
}
}
}
最后,这个方法通过上面提到的代码构建了一个Seq
类型的对象
And most importantly what is the type of the returned value?
object MainClass {
def main(args: Array[String]): Unit = {
val isList = Seq(1,2,3).isInstanceOf[List[Int]]
println(isList)
}
}
打印:
true
所以,类型是scala.collection.immutable.List
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
的默认实现是List
。
Why is not an Indexed collection type, like Vector? What is the logic behind all that?
因为不可变的设计。该列表是不可变的,并使其不可变并具有恒定的前置操作,但 O(n) 追加操作成本和 O(n) 访问第 n 个元素的成本。 Vector
具有持续有效的访问和通过 id、前置和追加操作添加元素的实现。
要更好地了解 List 在 Scala 中的设计方式,请参阅 https://mauricio.github.io/2013/11/25/learning-scala-by-building-scala-lists.html
What exactly happens when you evaluate expression:
Seq(1,2,3)
?
在 Scala 中,foo(bar)
是 foo.apply(bar)
的语法糖,除非 this
也有一个名为 foo
的方法,在这种情况下它是对隐式 this
接收者,即就像 Java,它等同于 this.foo(bar)
.
就像任何其他 OO 语言一样,方法调用的接收者 单独 决定如何处理该调用,因此在这种情况下,Seq
决定要做什么做。
Seq is a trait, right?
标准库中有两个Seq
:
trait Seq
,也就是类型。object Seq
,这是一个值。
So when you call it like that
Seq(1,2,3)
it must be some kind of a companion object? Or not?
是的,它必须是一个对象,因为您只能调用对象的方法。您不能在类型上调用方法,因此,当您看到方法调用时,它必须 是一个对象。总是。所以,在这种情况下,Seq
不可能是Seq
特征,它必须是Seq
对象。
请注意 "it must be some kind of a companion object" 不正确。从那段代码中您唯一可以看到的是 Seq
是一个对象。您无法从那段代码知道它是否是伴随对象。为此,您必须查看源代码。在这种特殊情况下,事实证明它 是 ,实际上是一个伴随对象,但您不能从您显示的代码中得出结论。
Is it some kind of a class that extends Seq?
没有。它 不可能 是 class,因为你只能调用对象的方法,而 classes 在 Scala 中不是对象。 (这不像 Ruby 或 Smalltalk,其中 classes 也是 Class
class 的对象和实例。)它 必须 是一个对象。
And most importantly what is the type of the returned value?
找出答案的最简单方法是简单地查看 the documentation for Seq.apply:
def apply[A](elems: A*): Seq[A]
Creates a collection with the specified elements.
A
: the type of the collection's elementselems
: the elements of the created collection- returns a new collection with elements elems
因此,如您所见,Seq.apply
的 return 类型是 Seq
,或更准确地说,Seq[A]
,其中 A
是表示集合元素类型的类型变量。
Is it Seq and if yes, why is not explicitly the extension class instead?
因为没有扩展名class。
此外,Scala 中的标准设计模式是伴生对象的 apply
方法 return 是伴生对象 class 或特征的实例。打破这个约定会很奇怪和令人惊讶。
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]
。这就是您需要知道的全部内容。这就是您可以知道的全部内容。
现在,Seq
是一个 trait
,并且无法实例化特征,因此 运行时类型 将是 class 的某个子class Seq
。但!你不能也不应该关心它是什么特定的运行时类型。
Why is not an Indexed collection type, like Vector? What is the logic behind all that?
你怎么知道下次你调用它时它不会 return a Vector
?一点都不重要,因为静态类型是 Seq
因此你只能调用它的 Seq
方法,你只能依赖 [=17= 的契约],即 Seq
的 post-conditions,不变量等。即使 如果 你知道它是 Vector
returned,你将无法利用这些知识做任何事情。
因此,Seq.apply
return 可能是最简单的事情 return,那就是 List
。