`++` - 两个Arrays上的运算符在使用类型参数时返回ArraySeq

时间:2018-03-09 15:36:16

标签: scala

我试图实现一个简单的二叉树,这就是我提出的:

object main {

  class Node[A]

  case class EmptyNode[A](value: A) extends Node [A]

  case class NonEmptyNode[A](left: Node[A], right: Node[A]) extends Node[A]

  def traverse[A](tree: Node[A]): Array[A] = tree match {
    case NonEmptyNode(l: Node[A], r: Node[A]) => traverse(l) ++ traverse(r)
    case EmptyNode(v: A) => Array(v)
  }

  def main(args: Array[String]): Unit = {
    val binaryTree =
      NonEmptyNode(
        NonEmptyNode(
          EmptyNode("He"),
          EmptyNode("llo ")
        ),
        NonEmptyNode(
          EmptyNode("Wor"),
          EmptyNode("ld")
        )
      )

    val output = traverse(binaryTree).reduce((a, b) => a + b)

    println(output)
  }
}

现在我想知道为什么它不起作用,告诉我:

Error:(11, 62) type mismatch;
 found   : scala.collection.mutable.ArraySeq[A]
 required: Array[A]
    case NonEmptyNode(l: Node[A], r: Node[A]) => traverse(l) ++ traverse(r)

当我将A修改为String时,它会起作用:

object main {

  class Node

  case class EmptyNode(value: String) extends Node

  case class NonEmptyNode(left: Node, right: Node) extends Node

  def traverse(tree: Node): Array[String] = tree match {
    case NonEmptyNode(l: Node, r: Node) => traverse(l) ++ traverse(r)
    case EmptyNode(v: String) => Array(v)
  }

  def main(args: Array[String]): Unit = {
    val binaryTree =
      NonEmptyNode(
        NonEmptyNode(
          EmptyNode("He"),
          EmptyNode("llo ")
        ),
        NonEmptyNode(
          EmptyNode("Wor"),
          EmptyNode("ld")
        )
      )

    val output = traverse(binaryTree).reduce((a, b) => a + b)

    println(output)
  }
}

导致" Hello World"打印。

1 个答案:

答案 0 :(得分:4)

由于对A类型一无所知,因此无法构建Array[A]。因为它无法构建两个Array[A]中的Array[A],所以它会回退到ArraySeq

如果您确实要构建数组,则必须为ClassTag提供A

object main {

  class Node[A]

  case class EmptyNode[A](value: A) extends Node [A]

  case class NonEmptyNode[A](left: Node[A], right: Node[A]) extends Node[A]

  import scala.reflect.ClassTag
  def traverse[A: ClassTag](tree: Node[A]): Array[A] = tree match {
    case NonEmptyNode(l, r) => traverse(l) ++ traverse(r)
    case EmptyNode(v) => Array(v)
  }

  def main(args: Array[String]): Unit = {
    val binaryTree =
      NonEmptyNode(
        NonEmptyNode(
          EmptyNode("He"),
          EmptyNode("llo ")
        ),
        NonEmptyNode(
          EmptyNode("Wor"),
          EmptyNode("ld")
        )
      )

    val output = traverse(binaryTree).reduce((a, b) => a + b)

    println(output)
  }
}

打印:

Hello World

如果没有关于Array[A]的其他信息,则无法构建A的原因是Array[A]可以根据A的大小具有不同的运行时表示:它将是不同的是布尔,整数,长整数或Object。如果您想避免在代码中无处不在ClassTag,请不要使用低级数组,而是使用一些真正的通用集合。