[英]Scala: issue with extractor objects, type inference
json4 具有以下類型:
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
-> List
?
IntelliJ的類型“推斷”幫助器建議為理解結果設置類型JValue
。 但是,在這種情況下,您會得到一個編譯錯誤。 這到底是什么錯? 為什么會發生這種混亂?
List[String]
? 好了,正如您在此處看到的那樣,這就是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
事實證明,在for
構造中for
模式匹配時,也會使用withFilter()
。 所以這...
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會變得混亂。 信任編譯器。 如果它編譯時沒有警告,則只需忽略錯誤的類型建議。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.