我的数组的Scala参数化假定为String?

use*_*121 1 scala parameterization

我已经阅读了一些关于Manifest和擦除避免技术的内容,这些技术允许Scala执行"new Array [Array [T]]"之类的操作,但我对这个有点难过....

我有一种方法可以将数组中的一堆行列表为电子表格.例如,想象一下像这样的2D数组:

11,   5,    4
8,    3,    7
2,    1,    4
Run Code Online (Sandbox Code Playgroud)

我写了一个方法,总结了该数组的列,并吐出了像[21,9,15]这样的一维数组

我想将它泛化为Ints(比如Doubles或Floats),当我添加参数和清单时,我得到编译错误.

这是代码

def sumGrid[T](grid: Array[Array[T]])(implicit m: ClassManifest[T]): Array[T] = {

  val sum = new Array[T](grid(0).size)

  for(i <- 0 until grid.size) {
    for(j <- 0 until grid(0).size) {
      sum(j) = sum(j) + grid(i)(j)
    }
  }  
  sum
}
Run Code Online (Sandbox Code Playgroud)

这是编译错误:

[ERROR] ...scala/euler/GridOperations.scala:126: error: type mismatch;
[INFO]  found   : T
[INFO]  required: String
[INFO]         sum(j) = sum(j) + grid(i)(j)
[INFO]                                  ^
[ERROR] one error found
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?为什么String"必需"?

par*_*tic 6

因为您使用+始终为字符串定义的运算符.任何类型都可以转换为String(toString始终定义),因此它适用于任何类型T.

但是您可以添加一些约束T以确保它对应于算术运算.例如,您可以使用implicits来获取Numeric定义类型添加的对象T:

def sumGrid[T](grid: Array[Array[T]])
(implicit m: ClassManifest[T], num: Numeric[T]): Array[T] = {

  val sum = new Array[T](grid(0).size)

  for(i <- 0 until grid.size) {
    for(j <- 0 until grid(0).size) {
      sum(j) = num.plus( sum(j), grid(i)(j) )
    }
  }  
  sum
}
Run Code Online (Sandbox Code Playgroud)