代码之家  ›  专栏  ›  技术社区  ›  Kurt Schelfthout

doto和有条件地设置属性

  •  3
  • Kurt Schelfthout  · 技术社区  · 14 年前

    (defn download-web-page
        "Downloads the webpage at the given url and returns its contents."
        [^String url ^String user ^String password]
        (with-open [client (doto (WebClient.)
                           (when user (.set_Credentials (NetworkCredential. user password ""))))]
        (.DownloadString client url)))
    

    因此,我只想将凭据设置为函数的参数。然而,它似乎不是这样工作的-当我用if替换when时也不是这样。

    如果我完全删除when,函数就可以正常工作。

    4 回复  |  直到 14 年前
        1
  •  3
  •   dreish    14 年前

    (defn download-web-page
      "Downloads the webpage at the given url and returns its contents."
      [^String url ^String user ^String password]
      (with-open [client (WebClient.)]
        (when user
          (.set_Credentials client (NetworkCredential. user password "")))
        (.DownloadString client url)))
    

    with-open 没有任何特别的要求 client close 方法,因此不需要在绑定向量中“完成”它。

        2
  •  4
  •   Michał Marczyk    14 年前

    (注意:这应该都是有希望的工作,但我不能在这个时候测试它。请自己检查一下。)

    (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 在有规律地混合时形成 let -基础版本应该做的很好。

    真正地 较少的 灵活,但更漂亮,比如说 ~guard 具有 (when ~guard) (doto-guard user (.setCredentials ...)) . 然而,选择某个特定版本的任何深层原因都必须来自更广泛的背景。)

    nil nil 当没有实际提供凭据时。

        3
  •  2
  •   wilkes    14 年前
    (defn download-web-page
      "Downloads the webpage at the given url and returns its contents."
      [^String url ^String user ^String password]
      (let [client (WebClient.)]
        (when user 
          (.set_Credentials client (NetworkCredential. user password "")))
        (with-open [client client]
          (.DownloadString client url)))
    

    (with-open [client client]... doto 它经常出现 保证一个宏,但我会先跳转到一个生成器函数:

    (defn build-web-client
      [^String user ^String password]
      (let [client (WebClient.)]
        (when user 
          (.set_Credentials client (NetworkCredential. user password "")))
        client))
    
    (defn download-web-page
      "Downloads the webpage at the given url and returns its contents."
      [^String url ^String user ^String password]
        (with-open [client (build-web-client user password)]
          (.DownloadString client url)))
    
        4
  •  1
  •   Didier A.    5 年前

    你可以筑巢 cond-> doto 像这样:

    (doto (java.util.Vector.)
      (cond-> (= 1 1) (.add "bla")))
    ;; => ["bla"]
    
    (doto (java.util.Vector.)
      (cond-> (= 1 2) (.add "bla")))
    ;; => []