1

假设我有一个例如二维数组,并且我将一些索引存储在元组中:

val testArray = Array.ofDim[Double](3, 4)
val ixs = (1,2)

我想直接使用这些元组,例如testArray(ixs). 但是,Function.tupled(testedArray _)返回“_ 必须遵循方法;不能遵循 Array[Array[Double]]”。

这是因为Array它实际上不是 的子类型Function3吗?如果是这样,如何绕过这个限制?我应该使用隐式来扩展ArrayOps或类似的东西吗?目前,我将数据存储在 aMap作为解决方法。

4

1 回答 1

2

数组数组不给予特殊处理;它们只是(某物)的数组。因此,没有通过元组访问它们的特殊方法。但正如您所建议的,您可以创建这样的方式。

你可以

implicit class ArrayOps2D[@specialized T](xss: Array[Array[T]]) {
  def apply(ij: (Int, Int)) = xss(ij._1)(ij._2)
  def apply(i: Int, j: Int) = xss(i)(j)
  def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t }
  def update(i: Int, j: Int, t: T) { xss(i)(j) = t }
}

你可能会想到做

implicit class ArrayOps2D[T](val xss: Array[Array[T]]) extends AnyVal {
  def apply(ij: (Int, Int)) = xss(ij._1)(ij._2)
  def apply(i: Int, j: Int) = xss(i)(j)
  def update(ij: (Int, Int), t: T) { xss(ij._1)(ij._2) = t }
  def update(i: Int, j: Int, t: T) { xss(i)(j) = t }
}

但这在我看来效果不佳。由于实施限制,您不能专门化 AnyVal。此外,如果您经常使用原语,前者可能会更好,因为它避免了对原语进行装箱(希望 JVM 可以处理避免对象创建),而如果您大部分时间都使用非原语,则后者效率更高(例如字符串),因为您没有(正式)创建对象。但是您的示例使用原语。

在任何情况下,如果您这样做,您将获得带有元组和成对参数的无缝双索引寻址(正如我所写的那样)。但是,您不能完全无缝地使用更新方法!它们大部分都可以工作,但它们不会自动提升数字类型。所以如果你有双打并且你写a(1,2) = 3它会失败,因为它没有找到update(Int, Int, Int)方法,并且不认为使用update(Int, Int, Double). 但是您可以通过转换(或者在这种情况下编写3d)来解决这个问题。

于 2013-03-03T21:21:19.490 回答