Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在cond范围内使用map_Map_Clojure - Fatal编程技术网

在cond范围内使用map

在cond范围内使用map,map,clojure,Map,Clojure,我已经无耻地从我找到的一个示例博客帖子(但现在似乎无法检索)中删除了几乎所有这些代码,该博客帖子演示了如何使用Java的套接字实现来维护简单的IRC连接 在使用这个示例时,我遇到了一个问题,我想加入一系列频道。我的第一个想法是在服务器var上存储通道向量,然后在模式匹配时对其进行分解。然而,到目前为止,这还不起作用。如果我将映射更改为对write函数的简单调用,则一切正常。然而,映射write函数似乎不起作用,我不知道为什么。有趣的是,如果我将map调用复制并粘贴到运行活动连接的repl中,它就

我已经无耻地从我找到的一个示例博客帖子(但现在似乎无法检索)中删除了几乎所有这些代码,该博客帖子演示了如何使用Java的套接字实现来维护简单的IRC连接

在使用这个示例时,我遇到了一个问题,我想加入一系列频道。我的第一个想法是在服务器var上存储通道向量,然后在模式匹配时对其进行分解。然而,到目前为止,这还不起作用。如果我将映射更改为对write函数的简单调用,则一切正常。然而,映射write函数似乎不起作用,我不知道为什么。有趣的是,如果我将map调用复制并粘贴到运行活动连接的repl中,它就会工作。。。这是因为这是在cond的范围内发生的吗?裁判可能是罪魁祸首吗?我刚刚闯入Clojure,所以我仍在努力想办法解决问题

不用多说,下面是代码:

  (ns irc
    (:import (java.net Socket)
            (java.io PrintWriter InputStreamReader BufferedReader)))

  (def server {:server "irc.example.net"
               :port 6667
               :channels ["#a" "#b"]})
  (def client {:realname "Lambda Bot" :nick "lambdabot"})

  (declare conn-handler)


  (defn in [a b]
    (re-find (re-pattern a) b))


  (defn startswith [a b]
    (in (str "^" a) b))


  (defn connect [server]
    (let [socket (Socket. (:server server) (:port server))
          in (BufferedReader. (InputStreamReader. (.getInputStream socket)))
          out (PrintWriter. (.getOutputStream socket))
          conn (ref {:in in :out out})]
      (doto (Thread. #(conn-handler conn server)) (.start))
      conn))


  (defn write [conn msg]
    (println msg)
    (doto (:out @conn)
      (.println (str msg "\r"))
      (.flush)))


  (defn conn-handler [conn server]
    (while (nil? (:exit @conn))
      (let [msg (.readLine (:in @conn))]
        (println msg)
        (cond
          (startswith "ERROR :Closing Link:" msg)
          (dosync (alter conn merge {:exit true}))
          (in " 001 " msg)
          ;; this guy below doesn't seem to work at all
          (map #(write conn (str "JOIN " %)) (:channels server))
          ;; this guy on the other hand seems to work fine
          ;;(write conn (str "JOIN " (first (:channels server))))
          (startswith "PING" msg)
          (write conn (str "PONG " (re-find #":.*" msg)))))))


  (defn login [conn user]
    (write conn (str "NICK " (:nick user)))
    (write conn (str "USER " (:nick user) " 0 * :" (:realname user))))

要运行它,您只需调用:(def irc(connect server))然后(登录irc客户端)。非常感谢您的帮助!谢谢。

map
是一个延迟操作,即直到需要时才执行。当从repl调用repl时,repl会导致它求值,因为它需要打印返回的值

您可以使用
doall
强制执行惰性操作

(doall (map ... ))
更好的方法是使用
doseq
而不是
map
map
用于将一组值转换为另一组值,
doseq
用于对一组值执行操作,而这正是您想要做的

(doseq [ch (:channels server)]
  (write conn (str "JOIN " ch)))

(doall(map…)
有时更容易编写,但我明白你的意思。啊,当然!考虑到map是懒惰的,我应该意识到这里发生了什么,但我想我在精神上遵从了REPL的行为,而没有考虑到它会强制进行评估。谢谢你纵容我。