我在这个片段中有一个奇怪的例外
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)
^ ^
答案 0 :(得分:2)
splitted(i)
是String
,++
(需要集合)会将字符串视为Array[Char]
,然后会产生公共超类型List[Any]
。< / p>
示例:
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)
答案 1 :(得分:2)
你是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 :(得分:1)
不确定您要对该代码执行什么操作,但这是一个可用的版本:
(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
答案 3 :(得分:0)
这很有效。
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))
另请注意to
和until
之间的区别。使用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)