首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在条件范围内使用地图

在条件范围内使用地图
EN

Stack Overflow用户
提问于 2012-11-12 10:44:04
回答 1查看 122关注 0票数 3

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

在使用这个例子的时候,我遇到了一个问题,我想加入一系列的频道。我的第一个想法是在服务器变量上存储一个通道矢量,然后在匹配模式时对其进行解构。然而,到目前为止,这并不起作用。如果我将map更改为对write函数的裸调用,则一切正常。然而,映射write函数似乎不起作用,我不知道为什么。有趣的是,如果我将map调用复制并粘贴到运行活动连接的repl中,它就会工作……那么这是因为这发生在cond的范围内吗?裁判有可能被责备吗?我刚刚进入Clojure,所以我仍然在努力弄清楚一些事情。

不再赘述,下面是代码:

代码语言:javascript
复制
  (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 (连接服务器)),然后调用(login irc client)。如有任何帮助,我们不胜感激!谢谢。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2012-11-12 11:41:47

map是一个惰性操作,也就是说,它直到需要时才会执行。当从repl调用时,repl会导致它求值,因为它需要打印返回值。

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

代码语言:javascript
复制
(doall (map ... ))

使用doseq而不是map会更好。map用于将一组值转换为另一组值,而doseq用于对一组值执行操作,这就是您想要做的事情。

代码语言:javascript
复制
(doseq [ch (:channels server)]
  (write conn (str "JOIN " ch)))
票数 6
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13337729

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档