我想写这样的东西(不工作):
(defn new-connection []
(let [c (atom 0)]
{:id #(swap! c inc)
:writebuf (ByteBuffer/allocate 8096)
:readbuf (ByteBuffer/allocate 8096)}))
这样我就可以使用(新连接)获得增量标识的地图,我需要单独定义计数器还是有办法将它与这个函数内联?
我想写这样的东西(不工作):
(defn new-connection []
(let [c (atom 0)]
{:id #(swap! c inc)
:writebuf (ByteBuffer/allocate 8096)
:readbuf (ByteBuffer/allocate 8096)}))
这样我就可以使用(新连接)获得增量标识的地图,我需要单独定义计数器还是有办法将它与这个函数内联?
这是一个非常普遍的问题。如果你稍微分解一下,你会发现你需要三样东西:1)创建新计数器的东西 2)连接计数器 3)接受 id 作为参数而不是调用计数器本身的新连接函数,因为这使得这个函数更一般。
(defn new-counter []
(partial apply swap! (atom 0) inc []))
(def connection-counter (new-counter))
(defn new-connection [id]
{:id id
:writebuf (ByteBuffer/allocate 8096)
:readbuf (ByteBuffer/allocate 8096)})
现在你可以像这样使用它:
(new-connection (connection-counter))
您可以使用closure
机制“内联”计数器:
(let [c (atom 0)]
(defn new-connection []
{:id (swap! c inc)
:writebuf :ByteBuffer
:readbuf :ByteBuffer})
(defn get-counter []
@c))
(get-counter)
=> 0
(new-connection)
=> {:id 1, :writebuf :ByteBuffer, :readbuf :ByteBuffer}
(new-connection)
=> {:id 2, :writebuf :ByteBuffer, :readbuf :ByteBuffer}
(get-counter)
=> 2
或者,如果您需要控制计数器起始值:
(defn create-connection-fn [init-counter-value]
(let [c (atom init-counter-value)]
(fn []
{:id (swap! c inc)
:writebuf :ByteBuffer
:readbuf :ByteBuffer})))
(def new-connection (create-connection-fn 10))
(new-connection)
=> {:id 11, :writebuf :ByteBuffer, :readbuf :ByteBuffer}
(new-connection)
=> {:id 12, :writebuf :ByteBuffer, :readbuf :ByteBuffer}
编辑。如果没有理由“隐藏”它,我建议您将计数器定义为分隔变量。