[英]Instantiating a class's subtype in the companion object's apply method in Scala
[英]Scala's apply method
我在Scala中构造一个列表,如下所示:
val list1 = List(1,2,3) //This is otherwise: List.apply(1,2,3) ---> A
现在我有下面一行。
list1(1) //which is otherwise list1.apply(1) ---> B
上面的行返回2,其类型为Int。
A和B行是List类中apply方法的调用。 List类肯定不会出现方法重载。 那么基于编译器对A和B的不同对待呢?
谁能帮我理解这一点。 谢谢!
这里有两种不同类型的游戏。 在第二个示例中,您将在List类的实例上调用apply
实例方法。 在第一个示例中,您根本没有在List类上调用任何东西,而是在List伴随对象上调用了apply方法。
在行中
val list1 = List(1,2,3)
您可以说在这种情况下,您正在对伴随对象调用方法,因为您没有List的实例,并且似乎在类本身上调用了apply。
这里有两种应用方法: List.apply
和LinearSeqOptimized.apply
。 主要区别在于,当您调用List(1, 2, 3)
您使用的是List随行对象apply方法;当您调用list1(1)
您使用的是从LinearSeqOptimized
特性( List
类继承)继承的apply方法从)。
以上答案很好地解释了原因。 让我详细解释一下。
当您调用val list1 = List(1,2,3)
,您正在调用对象List
,该对象List
是类List
的伴随对象,并且.apply()
调用.apply()
方法并返回List
实例。
override def apply[A](xs: A*): List[A] = xs.toList //return instance of class List.
现在,如果您查看类List
:
sealed abstract class List[+A] extends AbstractSeq[A] with LinearSeq[A] with Product with GenericTraversableTemplate[A, List] with LinearSeqOptimized[A, List[A]] {...}
您可以看到它继承了性状LinearSeqOptimized[A, List[A]]
。 如果您研究此特征,您可以看到apply()
方法为
/** Selects an element by its index in the $coll.
* Note: the execution of `apply` may take time proportional to the index value.
* @throws IndexOutOfBoundsException if `idx` does not satisfy `0 <= idx < length`.
*/
def apply(n: Int): A = {
val rest = drop(n)
if (n < 0 || rest.isEmpty) throw new IndexOutOfBoundsException("" + n)
rest.head
}
这意味着类List
也将继承此.apply
方法。 因此,当您调用list1(1)
,实际上是在调用此apply方法,该方法返回列表的特定索引值。
总而言之,在第一个代码中,您正在调用伴随对象List
.apply
方法,该方法创建列表并返回类List
实例;在第二种情况下,您正在调用List
类的.apply
方法,该方法返回该列表的特定值。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.