如何以更实用的方式从Clojure catch块中重现?

myb*_*ael 5 functional-programming clojure

对于我正在写的IRC机器人,我想继续尝试打开一个套接字,即使有一个UnkownHostException.我的第一个想法是这样的.

(defn open-socket [{:keys [host port] :as connection}]
  (try (java.net.Socket. host port)
    (catch java.net.UnknownHostException _ (recur connection))))
Run Code Online (Sandbox Code Playgroud)

但它不起作用,因为你不能从catch块中重现.所以我决定这样的事情:

  (let [socket (promise)
        _ (while (not (realized? socket))
            (try (deliver socket (java.net.Socket. host port))
              (catch java.net.UnknownHostException _)))
        socket @socket]
    ...
Run Code Online (Sandbox Code Playgroud)

这是有效的,但这是非常必要的.有没有更多功能性的方式我可以这样做,我看不到?

Ank*_*kur 13

只需添加一个or:

(defn open-socket [{:keys [host port] :as connection}]
  (or (try (java.net.Socket. host port)
           (catch java.net.UnknownHostException _ nil))
      (recur connection)))
Run Code Online (Sandbox Code Playgroud)