[英]Scala: Why does isInstanceOf[List[Any]] not work?
我試圖解決99個Scala問題中的問題7,在找出可以包含任何類型的List
的類型時遇到了一些困難。 因此,我查看了答案,發現它是List[Any]
。 我着手編寫如下實現:
def flatten(lst: List[Any]): List[Any] = lst match {
case Nil => Nil
case x::xs =>
(if (x.isInstanceOf[List[Any]]) { flatten(x) } else { List(x) }) :::
flatten(xs)
}
但是,這給了我以下編譯錯誤:
[error] <filename omitted>:<line number omitted>: type mismatch;
[error] found : Any
[error] required: List[Any]
[error] (if (x.isInstanceOf[Any]) { flatten(x) } else {List(x) })
[error] ^
[error] one error found
將isInstanceOf[List[Any]]
更改為isInstanceOf[List[_]]
會產生相同的編譯錯誤。
經過簡短的google搜索並咨詢了該解決方案 ,我實現了這一點:
def flatten(lst: List[Any]): List[Any] = lst match {
case Nil => Nil
case x::xs => x match {
case x: List[_] => flatten(x) ::: flatten(xs)
case _ => x :: flatten(xs)
}
}
效果很好。 那么,為什么Scala編譯器為什么為了進入該塊而必須傳遞x.isInstanceOf[Any]
(使它成為List[Any]
類型)時才認為x
具有Any
類型? 這是編譯器錯誤,還是我不理解的Scala的一部分?
謝謝!
在您的代碼中, x
是List[Any]
的頭:它是Any
,因此您會收到錯誤消息。 您需要將其轉換為List[Any]
,通過模式匹配,您可以非常優雅地進行操作:
def flatten(lst: List[Any]): List[Any] = lst match {
case Nil => Nil
case (x:List[Any])::xs => flatten(x) ::: flatten(xs)
case x::xs => List(x) ::: flatten(xs)
}
僅僅因為一個值通過了.isInstanceOf
檢查並沒有改變它的類型。 仍然是Any
。 但是可以強制轉換為List[Any]
所以,我認為你需要做
(if (x.isInstanceOf[List[Any]]) { flatten(x.asInstanceOf[List[Any]]) } else { List(x) }) ::: flatten(xs)
我不確定,但我認為原因是
case x: List[_] => flatten(x) ::: flatten(xs)
該版本的工作方式是同時執行檢查和強制轉換。
執行此操作時:
case x::xs =>
x
綁定到列表的開頭。 因此,如果列表的類型為List[Any]
,當然,其頭部的類型為Any
(而不是List[Any]
)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.