簡體   English   中英

Scala:為什么isInstanceOf [List [Any]]不起作用?

[英]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的一部分?

謝謝!

在您的代碼中, xList[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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM