當前位置:
首頁 > 最新 > 記錄一次函數式編程語法糖拆解過程

記錄一次函數式編程語法糖拆解過程

使用Scala,不僅可以優雅地編寫簡潔的代碼,又能減少很多低級錯誤;能快速進行開發,又能保證系統性能、團隊協作和長期維護。

夏洛克ITOA系統,很多部分都使用Scala編寫。相關的技術心得就很多

摘 要

Scala是一種集合了面向對象以及面向函數式的基於jvm的編程語言,所以編寫scala代碼,既可以完全類似java一樣的風格,也可以寫出基於函數式的天馬行空的『優雅』的代碼,spark裡面rdd相關的代碼就是scala函數式編程的極致體現,真正做到了到最後一刻才會計算的延遲載入。

不過相比面向對象的風格,函數式編程風格的代碼有時會難以理解,實際的執行順序難以琢磨,下面是一個我最近看過的一個例子,簡單記錄一下。

解讀過程

代碼如下,入口在方法def imperativelyComplete,這個方法的主要目的是基於akka http的RequestContext進行封裝,把當前http請求上下文傳給其他地方進行處理,不過這個不是本文的重點,本文的重點是imperativelyComplete方法的定義,大家可以先自行觀看幾秒鐘。

比較明顯可以看出的是,這個方法的輸入參數是一個函數(輸入為ImperativeRequestContext類型,沒有返回值),這種定義方法還是比較多見的,比如Loan Pattern

接著再看這個方法的方法體,會有一個類似類定義裡面的self annotation的 ctx:RequestContext,看到這裡有些同學可能就比較頭暈了,這個ctx是哪來的??

別著急,都知道scala糖多,我們可以藉助scalac這個工具,來看看去糖之後的樣子,為了去除掉不必要的依賴,讓scalac可以編譯通過,我寫了一個類似的例子(Test.scala):

執行scalar -Xprint:typer Test.scala

下面這個就是imperativelyComplete方法去糖之後的樣子,可以看到這個方法的輸入參數是一個函數,並且返回值也是一個函數,並且作為返回值的這個函數的輸入參數為Req類型

看到這裡就完全明白了。最開始例子裡面的返回值也是一個函數:RequestContext => Future[RouteResult],只是目前的這種寫法不是太明顯,如果能像去糖後把返回值的結構清晰的定義出來,就一目了然了。如果我們看一下akka http庫裡面關於路由Route的定義,就會發現兩者是一致的,所以在akka http的路由裡面用imperativelyComplete這個方法,才可以編譯通過。

結 論

函數式編程風格的代碼有時確實比較難讀懂,特別是在scala當中,結合implicit這種特性,就靈活度更大。如果一時看不懂,可以試著換種角度去理解(本文中我們在探尋ctx是哪來的,沒想到它卻是返回值的一部分),當然更推薦使用scalac這個工具來一探糖背後的組成。

夏洛克ITOA

Make Data Think

人工智慧 機器學習 IT運維


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 夏洛克ITOA 的精彩文章:

TAG:夏洛克ITOA |