【问题标题】:Scala's apply methodScala 的 apply 方法
【发布时间】:2023-03-29 11:16:02
【问题描述】:

我正在 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 的不同处理呢?

谁能帮我理解这一点。 谢谢!

【问题讨论】:

  • 行 A 和 B 不是对 List 类中的 apply 方法的调用。 B 行是,但 A 行是对 List companion object 上的 apply 方法的调用,因此行为不同。
  • 感谢您的解释!非常感谢。

标签: scala


【解决方案1】:

这里有两种不同的类型。在第二个示例中,您在 List 类的实例上调用 apply 实例方法。在您的第一个示例中,您根本没有在 List 类上调用任何东西,而是在 List 伴随对象上调用 apply 方法。

排队

 val list1 = List(1,2,3)

您可以看出,在这种情况下,您正在调用伴随对象的方法,因为您没有 List 的实例,并且似乎在类本身上调用 apply。

【讨论】:

  • 感谢您帮助我理解这个概念!
【解决方案2】:

这里有两种应用方法:List.applyLinearSeqOptimized.apply。主要区别在于,当您调用 List(1, 2, 3) 时,您使用的是 List 伴随对象 apply 方法,而当您调用 list1(1) 时,您使用的是从 LinearSeqOptimized trait 继承的 apply 方法(List 类继承自) .

【讨论】:

  • 感谢您的回答!!
【解决方案3】:

以上答案很好地解释了原因。让我更详细地解释一下。

当您调用val list1 = List(1,2,3) 时,您正在调用一个对象List,它是类List 的伴随对象,它又调用.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]] {...}

你可以看到它继承了 trait 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 的实例,在第二种情况下,您正在调用类 @987654339 的 .apply 方法@ 返回该列表的特定值。

【讨论】:

  • 感谢您的详细解释!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-24
相关资源
最近更新 更多