【问题标题】:Repeated parameters in overloaded constructor重载构造函数中的重复参数
【发布时间】:2012-07-22 03:04:00
【问题描述】:

我想在 Scala 中编写一个类,它可以像这样使用任意数量的字节或布尔值

class Bytes(data: Byte*) {
  def this(data: Boolean*) = this {
    val res: Array[Byte] = convBools2Bytes(data)

    res: _*
  }

  // […]
}

其中convBools2Bytes 是将Array[Boolean] 转换为Array[Byte] 的函数:

def convBools2Bytes(data: Array[Boolean]): Array[Byte]

这给了我以下编译器错误:

[error] Bytes.scala:5: no `: _*' annotation allowed here
[error] (such annotations are only allowed in arguments to *-parameters)
[error]     res: _*
[error]        ^

据我了解,res: _* 语句将Array[Byte] 转换为重复参数列表(如“Programming in Scala”, 2nd Ed. 中的第 8.8 节所述)。

为什么会出现这样的错误,我该如何避免?

【问题讨论】:

  • 我刚刚插入了convBools2Bytes 来说明问题。没有考虑。在实际实现中,这个块中有很多代码。所以在这个例子中它真的没有任何意义。

标签: scala constructor variadic-functions


【解决方案1】:

正如编译器所说,您只能在可变参数的参数中使用它。您试图让该块返回一个扩展的可变参数列表,这是不允许的。 如果您想使用该块,那么:

this({
  val res: Array[Byte] = convBools2Bytes(data)
  res
}: _*)

否则这也应该没问题

this(convBools2Bytes(data): _*)

但是您会遇到另一个问题,擦除将导致两者具有相同的签名并阻止编译。 我认为你最好不要超载

【讨论】:

  • 我认为数组是特殊情况,不会被删除
  • 通常是的,但是采用可变参数的方法会被编译为采用 scala.collection.Seq 的方法。
  • 谢谢,凯托。你的最后一句话是对的:现在我收到一个double definition 错误。有没有办法绕过它?
  • 我编辑更改了主构造函数,直接采用Array[Byte]。
  • 我在标准库中发现的一个技巧是明确指定一个额外的元素,例如。 g.: def foo(x: Int, xs: Int*)
猜你喜欢
  • 2021-09-14
  • 1970-01-01
  • 2012-11-30
  • 1970-01-01
  • 2017-01-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多