【问题标题】:How to return a type parameter that is a subtype of an Array?如何返回作为数组子类型的类型参数?
【发布时间】:2012-11-25 20:28:53
【问题描述】:

我不明白为什么这段代码在 Scala 中是不可能的:

  def getColumns[T <: Array[_]] ():Array[(String,T)] ={
     Array(Tuple2("test",Array(1.0,2.0,3.0)))
  }

编译器说:

Array[(String,Array[Double])] 类型的表达式不符合预期的 Array[(String, T)] 类型

我对这段代码有同样的错误:

 def getColumns[T <: Array[Double]] ():Array[(String,T)] ={
     Array(Tuple2("test",Array(1.0,2.0,3.0)))
  }

我的完整用例更清楚了,最后我选择了Array[AnyVal]

class SystemError(message: String, nestedException: Throwable) extends Exception(message, nestedException) {
  def this() = this("", null)
  def this(message: String) = this(message, null)
  def this(nestedException : Throwable) = this("", nestedException)
}

class FileDataSource(path:String) {
   val fileCatch = catching(classOf[FileNotFoundException], classOf[IOException]).withApply(e => throw new SystemError(e))

   def getStream():Option[BufferedSource]={
     fileCatch.opt{Source.fromInputStream(getClass.getResourceAsStream(path))}
   }
}

class CSVReader(src:FileDataSource) {

  def lines= src.getStream().get
  val head = lines.getLines.take(1).toList(0).split(",")
  val otherLines = lines.getLines.drop(1).toList

  def getColumns():Array[(String,Array[_])] ={
    val transposeLines = otherLines.map { l => l.split(",").map {
      d => d match {
        case String => d
        case Int => d.toInt
        case Double => d.toDouble
      }}.transpose }

    head zip transposeLines.map {_.toArray}
  }
}

你能给我一些解释或很好的链接来理解这些问题吗?

【问题讨论】:

    标签: arrays scala generics covariance contravariance


    【解决方案1】:

    因为您的函数必须能够使用任何T(任何数组类型),但是它总是会返回Array[(String,Array[Double])]

    一个更简单的工作签名是:

    def getColumns[T](): Array[(String,Array[T])]
    

    但在函数体中,您必须创建T 类型的数组。

    【讨论】:

    • 嗯,也许我的例子很傻,实际上getColumns可以返回其他数组类型,Int或Double,所以也许我的方法在这里或那里不好解决?
    • 最后,我完成了我的真实用例和我在这种情况下选择的解决方案
    【解决方案2】:

    您的函数签名需要复合返回类型中的T,但您给它一个Array[Double]。请注意T &lt;: Array[Double],而不是相反。以下代码有效:

    def getColumns[T >: Array[Double]] ():Array[(String,T)] ={
     Array(Tuple2("test",Array(1.0,2.0,3.0)))
    }
    

    不应该是你想要的,而只是为了阐述问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-12-14
      • 2022-01-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-13
      • 2020-11-22
      相关资源
      最近更新 更多