2017-07-26 106 views
1

在這個例子中不會發生:從陣列到WrappedArray隱式轉換時的模式匹配

scala> val a: Seq[Int] = Array(1,2,3) 
a: Seq[Int] = WrappedArray(1, 2, 3) 

隱式轉換髮生,Array轉換爲WrappedArray延伸Seq,如下解釋:Arrays Scala Doc

但這裏:

object MyObject { 

    def main(args: Array[String]): Unit = { 

    val a = Array(1,2,3) 
    // val a: Seq[Int] = Array(1,2,3) if added explicitly works 

    val result = a match { 
     case Seq(
     first, 
     second, 
     third 
    ) => (first, second, third) 
    } 
    println(result) 
    } 
} 

該代碼失敗:

Error:(9, 15) scrutinee is incompatible with pattern type; 
found : Seq[A] 
required: Array[Int] 
     case Seq(

隱式轉換不會發生,爲什麼?

+0

作爲一個實用的解決方案,您可以隨時「檢索」您的數組。 'toSeq'方法不會構造一個新的集合,所以它只會包裝數組。來源:http://www.scala-lang.org/api/2.12.1/scala/Array.html#toSeq:Seq [A] –

回答

3

布拉克埃米爾給了一個理由來模式匹配不允許隱式轉換(以下是從www.scala-archive.org報價)的語言設計決定:

1)類型檢查模式依賴於靜態信息(喜歡到處 其他在編譯器中)。在模式的情況下,「預期類型」是向下傳播的,以便鍵入可變綁定模式,並且更多地通常驗證該模式是有意義的。當然,預期類型開始於監票人(也就是選擇器 表達式,也就是匹配的內容)。

2)模式匹配的翻譯使用(幾乎)每種方式可以避免多餘的類型測試 。這意味着源代碼中存在的案例 被「壓縮」成一種決策樹 圖。這後來被翻譯成代碼。

輸入隱式轉換。讓監票人的類型不同 那麼模式意味着我們不能在模式中使用預期的類型。 因此,我們必須鍵入檢查模式,而不管檢查者的類型爲 。

這可能仍然是可行的(小心在這裏,誰可以預見毛髮 與序列模式的互動等)。我們可以說,模式具有獨立於預期類型的​​ 類型,並且類型檢查將會看到 監察者的類型是否符合模式類型 (可能在應用某種隱式轉換之後)。

但是這原來是一個非規範。

implicit def fbTypeToFoo ... 
implicit def fbTypeToBar ... 

fb match { 
    case Foo(...) => 
    case Bar(...) => 
} 

什麼似乎真的需要是「需要通過」申請的意見,這意味着 「內部」的模式匹配。

這與本任務執行任務2)的衝突。在存在 隱式轉換的情況下,模式匹配的任務實際上會將一個 級別推得更深,因爲最外層的模式將始終匹配(畢竟有一個 轉換)。這是很煩人的實現和 指定,因爲有花紋和圖案,而不從scrutinee類型隱式轉換 可能會被混合,就像在

implicit def FooToBar... 
myFoo match { 
    case Foo(...) 
    case Bar(...) 
    case Foo(...) 
} 

假設有一個頂級「富「永遠不會進入」酒吧「的情況 現在是無效的(畢竟有轉換)。基本上失去了所有最優層次的希望。儘管當前匹配器 將加入模式1和3的其餘部分,但帶有隱式調用的假設匹配器 不能設計爲這樣,因爲它違反了第一個匹配策略 。