【问题标题】:Scala: Generic array with default parameter value in constructorScala:构造函数中具有默认参数值的通用数组
【发布时间】:2013-09-21 13:15:23
【问题描述】:

我有几个关于 scala 泛型和默认参数值的问题。

假设,我有以下类定义(其中 Stack[E] 是一个特征)

class ImmutableStack[E](capacity: Int = 10, elems: Array[E] = new Array[E](capacity))(implicit ev: ClassTag[E]) extends Stack[E]

当我尝试编译该代码时,它给出了两个错误:

scala: cannot find class tag for element type E
class ImmutableStack[E <: Any](capacity: Int = 10, elems: Array[E] = new Array[E](capacity))(implicit ev: ClassTag[E]) extends SedgewickStack[E] {
                                                                 ^

还有:

scala: not found: value capacity
class ImmutableStack[E <: Any](capacity: Int = 10, elems: Array[E] = new Array[E](capacity))(implicit ev: ClassTag[E]) extends SedgewickStack[E] {
                                                                                  ^

谁能解释一下:

  1. 为什么构造函数定义中的其他参数不能使用容量参数?
  2. 为什么 ClassTag ev 不适用于默认参数值,即new Array[E](capacity)?

当我删除 elem 参数的默认值时 - 一切正常。

提前感谢您的任何回答。

【问题讨论】:

  • 这可能不是一个完整的答案,但是:我认为capacity 实际上不在构造函数声明的范围内。就此而言,我不知道是否有任何语言允许交叉引用构造函数或函数参数;您只能在正文中访问它们。
  • @ViktorSeifert:引用capacity 不是问题。您只需将其移至附加参数组。这工作正常def test(a: Int)(b: Int = a) = a + b; test(1)()。但您无法访问下一组 (ev) 的参数。
  • @senia 这对构造函数有用吗?
  • @ViktorSeifert:您可以尝试一下:class Test(a: Int)(b: Int = a) { val c = a + b }; new Test(1)().c 工作正常。在其他情况下,您可以使用工厂方法。

标签: scala generics parameters constructor


【解决方案1】:

您只能将先前参数列表中的值用作构造函数和方法中的默认值,而不能使用相同的值:

class ImmutableStack[E <: Any](capacity: Int = 10)(elems: Array[E] = new Array[E](capacity))(implicit ev: ClassTag[E])

要解决无法使用隐式类标签的问题,我能提供的最好方法是

class ImmutableStack[E <: Any : ClassTag](capacity: Int = 10)(elems: Array[E] = null) {
  val realElems = if (elems != null) elems else new Array[E](capacity)
}

【讨论】:

  • 感谢您的提示。我也使用了与 elems 参数的默认值相同的方法。但是,由于隐式 ClassTag 仅作为最后一个参数列表提供而在前面的参数列表中不可用,因此无法构造一个具有泛型类型参数作为默认参数值的数组,我对吗?
猜你喜欢
  • 2014-02-25
  • 2017-09-27
  • 1970-01-01
  • 1970-01-01
  • 2016-09-05
  • 2015-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多