1

我有一种算法可以对某些对象的索引序列进行操作:它得到两个这样的序列并且应该输出一个结果序列。我希望它至少能够使用:

  • 字符串中的字符
  • 文本数组中的行(字符串)

为简单起见,我们假设该算法只是构造一个新的对象序列,从每个原始序列中一个接一个地获取对象。在某些特殊情况下,我必须返回所需类型的空对象序列或原始对象。我将在原始序列上使用的唯一两个操作是:

  • 通过索引获取第i个元素
  • 获取序列的大小

我当前的代码如下所示:

class GenericTest[C, T <: IndexedSeq[C]](a: T, b: T) {
  def run: T = {
    // special case #1: need to return empty sequence here
    if (a.size == 0) {
      // what I've tried:

      return new T()
      // fails: "class type required but T found"

      return Seq[C]()
      // fails: "type mismatch; found : Seq[C] required: T"

      return Array[C]()
      // fails: "not enough arguments for method apply: (implicit
      // evidence$2: scala.reflect.ClassTag[C])Array[C] in object
      // Array. Unspecified value parameter evidence$2."

      return Array.ofDim[C](0)
      // fails: "No ClassTag available for C"
      // "not enough arguments for method ofDim: (implicit
      // evidence$3: scala.reflect.ClassTag[C])Array[C].
      // Unspecified value parameter evidence$3."
    }

    // special case #2: need to return original input here
    if (a == b) {
      return a
      // it works
    }

    val result = new MutableList[C]

    for (i <- 0 until scala.math.min(a.size, b.size)) {
      result += a(i)
      result += b(i)
    }

    // what I've tried:

    return result
    // fails: "type mismatch; found : result.type (with underlying
    // type scala.collection.mutable.MutableList[C]) required: T"

    return result.toIndexedSeq
    // fails: "type mismatch; found : scala.collection.immutable.IndexedSeq[C]
    // required: T"
  }
}

所以,基本上,问题是——我如何正确设置 Scala 泛型来完成这项任务:

  • 返回空的对象序列
  • 返回构造的对象序列
  • 返回原始输入

我想这个问题需要类型的协方差/逆变注释,我的协方差-fu 似乎缺乏......

4

1 回答 1

4

由于 scala 中的列表是协变的,因此您可以将任何对象添加到列表中,只要它是列表类型的子类型即可。

   class GenericTest[C](a: IndexedSeq[C], b: IndexedSeq[C]) {
      def run: IndexedSeq[C] = {
        // special case #1: need to return empty sequence here
        if (a.size == 0) {
          return IndexedSeq.empty[C]
        }

        // special case #2: need to return original input here
        if (a == b) {
          return a
        }

        val result = mutable.ArrayBuffer[C]()

        for (i <- 0 until scala.math.min(a.size, b.size)) {
          result += a(i)
          result += b(i)
        }
        result.toIndexedSeq
      }
    }
于 2013-10-12T16:03:48.350 回答