閱讀756 返回首頁    go 阿裏雲 go 技術社區[雲棲]


話說模式匹配(3) 模式匹配的核心功能是解構

https://www.artima.com/scalazine/articles/pattern_matching.html
這篇文章是odersky談scala中的模式匹配的一段對話,我做了部分片段翻譯(不是連貫的):

模式可以嵌套,就像表達式嵌套,你可以定義深層的模式,通常一個模式看起來就像一個表達式。它基本上就是同一類事情。
它看起來像一個複雜的對象樹構造表達式,隻是漏掉了new關鍵字。事實上在scala當你構造一個對象,你不需要new關鍵字
然後你可以在一些地方用變量做站位符替代對象樹上實際的東西。

本質上,當你需要通過外部來構造對象圖,模式匹配是必要的,因為你不能對這些對象添加方法
有很多場景的例子,XML是一個,所有解析過的數據落入不同的分類。
舉例,一個標準的場合是當你用編譯器解析抽象語法樹的時候模式匹配是必要的。

解構對象 (De-constructing objects)
Bill Venners: 你說模式像表達式,但它更像“逆表達式”,不同於插入值並得到結果(構造一個對象的過程),你放入一個值,當它匹配,一串值彈出來。
Martin Odersky: 是的,它確實是反向構造,我可以通過嵌套的構造器來構造對象。我有一個方法一些參數,通過這些參數可以構造出負責的對象結構。模式匹配正好相反,它從一個複雜的對象結構中抽出原來用於構造這個對象的參數

可擴展性的兩個方向(Two directions of extensibility)

擴展性的另一個概念是數據結構相對固定,你不想改變它,但你想要用到的行為操作是開放的。你隨時都想要添加新的操作。
典型的例子是編譯器,編譯器用語法樹表達你的程序,隻要你沒有改變你的語言,語法樹就不會變,一直都是同一顆樹
但編譯器想要這棵語法樹每天改變。明天你或許想到一種新的優化在遍曆樹的階段。

所以,你想采取的辦法是操作定義在你的語法樹外部,否則你要不斷的添加新方法

這個工作正確的方向,取決於你想在那個方向擴展,如果你想要擴展新的數據,你選擇經典的麵向對象通過虛方法調用實現。如果你想保持數據固定,擴展新的操作,模式更適合。
實際上有一個設計模式,不要和模式匹配混淆,在麵向對象程序中稱為“訪問者模式”,也可以用麵向對象的方式表達模式匹配的方式,基於虛方法委派的。

但實際中用visitor模式是非常笨重的,不能像模式匹配那樣輕鬆的做很多事。你應該終結笨重的vistors,同時在現代虛擬機技術中也證明vistor模式遠沒有模式匹配有效。所有這些原因,我想應該為模式匹配定義一套規則

ps, 前段時間王垠同學在批判設計模式的一篇文章中,提到visitor模式就是模式匹配。
可以對比一下scala語言通過case class/extractor方式在語言級別支持模式匹配,與通過visitor模式來達到同樣的效果時的代碼差別。


文章轉自 並發編程網-ifeve.com

最後更新:2017-05-22 20:03:18

  上一篇:go  5月22日雲棲精選夜讀:PHP學習路線圖
  下一篇:go  Java中Redis的使用教程