Frage Wie kann ich von einem Clojure-Catch-Block auf eine funktionellere Art und Weise zurückkehren?


Für einen IRC-Bot, den ich schreibe, möchte ich weiter versuchen, einen Socket zu öffnen, selbst wenn es einen gibt UnkownHostException. Mein erster Gedanke war so etwas.

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

Aber es funktioniert nicht, weil Sie nicht von einem catch-Block zurückkehren können. Also entschied ich mich stattdessen für so etwas:

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

Und das funktioniert, aber es ist furchtbar notwendig. Gibt es einen funktionelleren Weg, den ich machen könnte, den ich nicht sehen kann?


5
2018-06-23 05:25


Ursprung


Antworten:


Fügen Sie einfach ein ein or:

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

13
2018-06-23 07:14



Eine Möglichkeit könnte so etwas sein?

(let [make-socket #(try (java.net.Socket. host port)
                     (catch java.new.UnknownHostException _))
      socket-attempts (repeatedly make-socket)
      socket (first (drop-while nil? socket-attempts))]
  socket)

0
2018-06-23 05:51