json4 has以下类型:
sealed abstract class JValue
case class JString(s: String) extends JValue
//etc
我有以下json值:
val json: JValue = JString("hi")
我将其用于理解中:
val token = for {
JString(s) <- json
} yield s
以下是问题:
实际上,令牌将被评估为List("hi")
,即List[String]
类型的实例。我的理解是它应该是Option[String]
。为什么Option
- &gt; List
IntelliJ的类型 - “推理”帮助器,建议为for-comprehension的结果设置类型JValue
。然而,当你这样时,你会收到编译错误。这里有什么问题?为什么会发生混乱?
答案 0 :(得分:1)
List[String]
?好吧,你可以看到here,这就是json4s作者所选择的。他们本可以使用Vector[String]
或Array[String]
,但决定List[String]
。我认为他们有充分的理由。
withFilter()
与它有什么关系?
正如我们在Scala类的第一天所学到的,for
不是一个控制流语言构造,但实际上是用于美化嵌套map
/ flatMap
构造的语法糖
for {
b <- a // flatMap()
if b.isSomeCondition // withFilter()
c <- b // map()
} yield c
事实证明,withFilter()
构造中的模式匹配时也使用for
。所以这......
for {
JString(s) <- json
} yield s
...被翻译成这个(大致)。
json.withFilter{
case JString((s @ _)) => true
case _ => false
}.map{
case JString(s @ _) => s
}
json4s的作者认为withFilter()
应该返回List
,因此这是for
理解的结果。
IntelliJ的语法检查和建议引擎非常好,但它并不完美。 Scala代码可能变得相当复杂,IntelliJ混淆并不罕见。相信编译器。如果它在没有警告的情况下编译,那么只需忽略错误类型的建议。