1

たとえば、二次元配列があり、いくつかのインデックスをタプルに格納しているとします。

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

これらのタプルを直接使用したいと思いtestArray(ixs)ます。ただし、Function.tupled(testedArray _)「_ はメソッドに従う必要があります。Array[Array[Double]] に従うことはできません」が返されます。

これArrayは、実際には のサブタイプではないためFunction3ですか? もしそうなら、この制限を回避するにはどうすればよいですか? 暗黙を使用して拡張するArrayOpsか、同様のものを使用する必要がありますか? 現在、回避策としてデータをに保存していますMap

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 がオブジェクト作成の回避を処理できることを願っています)、プリミティブを頻繁に使用している場合は前者の方がおそらく優れていますが、非プリミティブがほとんどの場合 (オブジェクトを(正式に)作成しないためです。しかし、あなたの例ではプリミティブを使用しています。

いずれにせよ、これを行うと、タプルと引数のペアを使用したシームレスな 2 つのインデックスのアドレス指定が可能になります (私が書いたように)。ただし、更新メソッドを完全にシームレスに使用することはできません! それらはほとんど機能しますが、数値型を自動的に昇格させることはありません。したがって、double があり、メソッドをa(1,2) = 3見つけられず、 . しかし、変換を行う (この場合は を書く) ことで、自分で修正できます。update(Int, Int, Int)update(Int, Int, Double)3d

于 2013-03-03T21:21:19.490 に答える