(Примечание. Надеемся, что все это сработает, но я не могу проверить это в настоящее время. Пожалуйста, сделайте свою собственную проверку работоспособности.)
Вы могли бы написать
(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
подойдет.
(Если этот шаблон подходит для действительно часто для вас, макрос можно сделать более гибким ... Также заманчиво сделать его немного менее гибким, но красивее, скажем заменив ~guard
на (when ~guard)
, чтобы в момент использования можно было написать (doto-guard user (.setCredentials ...))
. Однако любая серьезная причина выбора конкретной версии должна исходить из более широкого контекста.)
Разделение на два функциональных тела - это просто вопрос стиля - я предпочитаю не писать nil nil
, когда учетные данные фактически не предоставлены.