Scala在迭代中匹配,奇怪的编译器错误

时间:2018-06-20 13:03:38

标签: scala

编译后的一小段Scala代码 它给出了一个奇怪的错误。

import scala.collection.mutable.ListBuffer

object main {
  def main(args: Array[String]) {

    val rs = new ListBuffer[String]()
    val ns = scala.collection.mutable.Map[String, String]()

    "A very long string".split("\\ ") foreach { word =>

        word match {
            case x if x.length() > 7  => ns += x -> "="
            case _ =>   rs += word 
        }
    }
  }
}

给出以下错误:

test.scala:11: error: type arguments [String,Iterable[java.io.Serializable] with PartialFunction[String with Int,String] with scala.collection.generic.Subtractable[String,Iterable[java.io.Serializable] with PartialFunction[String with Int,String] with scala.collection.generic.Subtractable[String,Equals]]{def seq: Iterable[java.io.Serializable] with PartialFunction[String with Int,String]}] do not conform to trait Subtractable's type parameter bounds [A,+Repr <: scala.collection.generic.Subtractable[A,Repr]]
    "A very long string".split("\\ ") foreach { word =>
                                              ^
one error found

有任何提示吗?

2 个答案:

答案 0 :(得分:1)

之所以发生这种情况,是因为您的模式匹配返回了冗长的复合类型:

[String,Iterable[java.io.Serializable] with PartialFunction[String with Int,String] with scala.collection.generic.Subtractable[String,Iterable[java.io.Serializable] with PartialFunction[String with Int,String] with scala.collection.generic.Subtractable[String,Equals]]{def seq: Iterable[java.io.Serializable] with PartialFunction[String with Int,String]}]

线性化中的一种类型是Subtractable[String, Iterable[Serializable]],而您的类型不符合其类型约束:

trait Subtractable[A, +Repr <: Subtractable[A, Repr]

要解决此问题,请在foreach上使用类型注释帮助编译器:

"A very long string"
  .split("\\")
  .foreach[Unit] {
  case x if x.length() > 7 => ns += x -> "="
  case word => rs += word
}

作为旁注,也许您会发现以下实现很有用:

val (largerThanSeven, smallerThanSeven) = "A very long string"
  .split("\\")
  .partition(_.length > 7)

val largerThanSevenMap = largerThanSeven.map(_ -> "=").toMap

答案 1 :(得分:1)

问题在这里:

ns += x -> "="

我猜想目的是将键x和值"="放入可变映射。

如果更改为,则会编译

ns(x) = "="

问题在于->的转换中包含隐式,并且错误消息中的类型被怪异地推断为怪异的字符串。