【问题标题】:Why I've got type mismatch exception?为什么我有类型不匹配异常?
【发布时间】:2014-01-13 18:31:41
【问题描述】:

我在这个 sn-p 中遇到了一个奇怪的异常

 val splitted = "This is a text that to test something".split("\\,|\\ ")
 val map = mutable.Map[Int, List[String]]()
 (0 to splitted.length).foreach {
     case i =>map(i) = map.getOrElse(i,List[String]("")) ++ splitted(i)
 }

但我有这个例外:

type mismatch;
 found   : List[Any]
 required: List[String]
      case i =>map(i) = map.getOrElse(i,List("")) ++ splitted(i)
                                              ^                                                  ^

【问题讨论】:

  • 你确定这段代码是正确的吗?你想做什么 ? , map(i) 期待一个 int , List

标签: scala


【解决方案1】:

你是Any推理的又一个受害者。

scala> map.getOrElse(7,List[String](""))
res3: List[String] = List("")

scala> res3 ++ "abc"
res4: List[Any] = List("", a, b, c)

-Xlint 也是这样:

scala> (0 to splitted.length).foreach {
     case i =>map(i) = map.getOrElse(i,List[String]("")) ++ splitted(i)
 }
<console>:12: error: type mismatch;
 found   : List[Any]
 required: List[String]
                   case i =>map(i) = map.getOrElse(i,List[String]("")) ++ splitted(i)
                                                                       ^

scala> val res3 = { map.getOrElse(7,List[String]("")) }
<console>:6: warning: Unused import
import collection.mutable
                  ^
res3: List[String] = List("")

scala> res3 ++ "abc"
<console>:11: warning: a type was inferred to be `Any`; this may indicate a programming error.
              res3 ++ "abc"
                      ^
res1: List[Any] = List("", a, b, c)

不幸的是,-Xlint 警告被错误所掩盖。

并且,在-Xlint -Xfatal-warnings 下,警告没有机会出错:

scala> (0 to splitted.length).foreach {
     case i =>map(i) = map.getOrElse(i,List[String]("")) ++ splitted(i)
 }
<console>:11: error: type mismatch;
 found   : List[Any]
 required: List[String]
                   case i =>map(i) = map.getOrElse(i,List[String]("")) ++ splitted(i)
                                                                       ^

如果警告不在闭包内,那么您会在-Xlint -Xfatal-warnings 下收到有用的消息:

val ss: List[String] = (null: mutable.Map[Int,List[String]]).getOrElse(0,List.empty[String]) ++ "abc"

【讨论】:

    【解决方案2】:

    splitted(i) 是一个String++(它需要一个集合)将String 视为Array[Char],然后产生公共超类型List[Any]

    例子:

    val list = List("a", "b") ++ "hello"
    println(list) //prints List(a, b, h, e, l, l, o) and is of type List[Any]
    

    如果插入的位置无关紧要,那么我会这样做:

    case i => map(i) = splitted(i) :: map.getOrElse(i,List[String](""))
    

    如果应该附加:

    case i => map(i) = map.getOrElse(i,List[String]("")) :+ splitted(i)
    

    【讨论】:

    • 字符串是一个集合。 Seq('a','b') ++ "cde"
    • 也是刚刚想到的,修改了一下。
    【解决方案3】:

    不确定您要使用该代码做什么,但这是一个工作版本:

    (0 to splitted.length-1).foreach {
      case i =>map(i) = (map.getOrElse(i,List[String]("")) :+ splitted(i))
    }
    

    将创建:

    println(map)
    Map(2 -> List(, a), 5 -> List(, to), 4 -> List(, that), 7 -> List(, something), 1 -> List(, is), 3 -> List(, text), 6 -> List(, test), 0 -> List(, This))
    

    编辑:也许您需要以下内容:

    splitted.zipWithIndex.map{case (s,i)=>(i,s)}.toMap
    

    导致:

    Map(0 -> This, 5 -> to, 1 -> is, 6 -> test, 2 -> a, 7 -> something, 3 -> text, 4 -> that)
    

    或更高效:

    ((0 to splitted.length-1) zip splitted).toMap
    

    【讨论】:

      【解决方案4】:

      这行得通。

       val splitted = "This is a text that to test something".split("\\,|\\ ")
       val map = scala.collection.mutable.Map[Int, List[String]]()
       (0 until splitted.length).foreach {
           case i =>map(i) = map.getOrElse(i,List[String]("")) :+ splitted(i)
       }
      

      哪些输出:

      scala.collection.mutable.Map[Int,List[String]] = Map(2 -> List("", a), 5 -> List("", to), 4 -> List("", that), 7 -> List("", something), 1 -> List("", is), 3 -> List("", text), 6 -> List("", test), 0 -> List("", This))
      

      另外,请注意tountil 之间的区别。使用to in 将给出和ArrayOutOfBoundsException

      scala> val l = List(1,2,3)
      l: List[Int] = List(1, 2, 3)
      scala> 0 to l.length
      res51: scala.collection.immutable.Range.Inclusive = Range(0, 1, 2, 3)
      scala> 0 until l.length
      res52: scala.collection.immutable.Range = Range(0, 1, 2)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-05-23
        • 2010-12-13
        • 1970-01-01
        • 2022-01-26
        • 1970-01-01
        • 2012-07-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多