(注:這應該都希望工作,但我不能在這個時候測試它,請給它自己的運行狀況檢查。)
你可以寫
(defn download-web-page
"Downloads the webpage at the given url and returns its contents."
([^String url] (download-web-page url nil nil))
([^String url ^String user ^String password]
(with-open [client (doto (WebClient.)
(-> (.set_Credentials
(NetworkCredential. user password ""))
(->> (when user))))]
(.DownloadString client url))))
這似乎很令人費解,以我,雖然。另一種方法:
(defn download-web-page
"Downloads the webpage at the given url and returns its contents."
([^String url] (download-web-page url nil nil))
([^String url ^String user ^String password]
(with-open [client (let [c (WebClient.)]
(when user
(.set_Credentials
(NetworkCredential. user password "")))
c)]
(.DownloadString client url))))
從第一個版本的令人費解的->
/->>
模式可以被抽象掉了宏:
(defmacro doto-guard [guard action]
`(-> ~action ~guard))
然後,你可以寫
(doto (WebClient.)
(doto-guard (when user) (.setCredentials ...)))
這樣做的不錯屬性,您可以在單個doto
表單中多次使用它,同時在常規doto
子句中進行混合。好吧,無論如何,如果這種事情在你的代碼中出現得更多,那就很好。否則基於let
的版本應該沒問題。
(如果這種模式往往出現真的你,宏可以更加靈活......它也很誘人,使其略少靈活,但是更漂亮,用(when ~guard)
更換~guard
說,等在使用時,人們會寫(doto-guard user (.setCredentials ...))
。但是,選擇特定版本的任何深層原因必須來自更廣泛的背景,但是)。
分成兩個函數體只是一個風格問題 - 我更喜歡當沒有提供憑證時,不要編寫nil nil
。
我從它被寫在需要的憑據設置的方式承擔連接打開之前。您的代碼首先打開,然後設置憑據。我不知道這是否有問題。 – 2010-09-14 23:47:04
不,打開沒有打開任何東西。它*僅*保證當控制流離開with-open形式時,綁定變量是(.close)d,無論是通過異常還是正常返回。 – dreish 2010-09-15 17:50:53
是的,你說得對。我的錯。 – 2010-09-15 18:04:11