Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/dart/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
如何编写id递增的clojure工厂函数?_Clojure - Fatal编程技术网

如何编写id递增的clojure工厂函数?

如何编写id递增的clojure工厂函数?,clojure,Clojure,我想写这样的东西(不起作用): 为了使用(新连接)以增量方式获取id映射,我需要单独定义计数器还是有办法使用此函数将其内联?您可以使用闭包机制“内联”计数器: 或者,如果需要控制计数器开始值: (defn create-connection-fn [init-counter-value] (let [c (atom init-counter-value)] (fn [] {:id (swap! c inc) :writebuf :ByteBuffer

我想写这样的东西(不起作用):


为了使用(新连接)以增量方式获取id映射,我需要单独定义计数器还是有办法使用此函数将其内联?

您可以使用
闭包
机制“内联”计数器:

或者,如果需要控制计数器开始值:

(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}

编辑。如果没有理由“隐藏”计数器,我建议您将计数器定义为分离变量。

您可以使用
闭包
机制“内联”计数器:

或者,如果需要控制计数器开始值:

(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}

编辑。如果没有理由“隐藏”计数器,我建议您将计数器定义为分离变量。

这是一个非常普遍的计数器问题。如果你稍微分解一下,你会发现你需要三样东西: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))

这是一个非常普遍的问题,有一个计数器。如果你稍微分解一下,你会发现你需要三样东西: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))

视情况而定,您对引用透明度的重视程度如何?这是否指mobyte在下面的编辑中关于“隐藏”计数器的评论?当涉及对象计数时,您能期望引用透明度吗?我怀疑。视情况而定,你对引用透明度有多大的重视?这是指mobyte在下面的编辑中关于“隐藏”计数器的评论吗?当涉及对象计数时,你能期望引用透明度吗?我怀疑。谢谢你的回答。有一个问题,我读到在函数中定义变量(比如(defn…(def…))不是一个好主意。这适用于在上述let中定义函数吗?@georgek No.
let
over
defn
不是常见的clojure构造(人们似乎不喜欢它,尽管我自己也喜欢它),但它在概念上没有什么错。相反,def中的def确实存在问题。当var位于函数外部(可能显式传递给它)时,控制函数的行为就容易多了。这样就更容易使用任何可以计数并返回下一个值的东西。在释放def(n)的情况下,它只是原子。反对使用let-over-def的更重要原因是很难引入新功能来操作计数器-它们必须成为
let
范围的一部分。由于我们使用函数来组合函数(而不是名称空间),我的直觉告诉我要将计数器定义为函数外的变量。@JacekLaskowski感谢您的评论。是的,你说得对。我已经在编辑中提到了这一点。顺便说一句,整个答案是关于如何“内联”计数器与函数,但不是关于为什么你应该这样做)你最初(主要)的答案现在不是鼓励而不是劝阻吗?:-)谢谢你的回答。有一个问题,我读到在函数中定义变量(比如(defn…(def…))不是一个好主意。这适用于在上述let中定义函数吗?@georgek No.
let
over
defn
不是常见的clojure构造(人们似乎不喜欢它,尽管我自己也喜欢它),但它在概念上没有什么错。相反,def中的def确实存在问题。当var位于函数外部(可能显式传递给它)时,控制函数的行为就容易多了。这样就更容易使用任何可以计数并返回下一个值的东西。在释放def(n)的情况下,它只是原子。反对使用let-over-def的更重要原因是很难引入新功能来操作计数器-它们必须成为
let
范围的一部分。由于我们使用函数来组合函数(而不是名称空间),我的直觉告诉我要将计数器定义为函数外的变量。@JacekLaskowski感谢您的评论。是的,你说得对。我已经在编辑中提到了这一点。顺便说一句,整个答案是关于如何“内联”计数器与函数,但不是关于为什么你应该这样做)你最初(主要)的答案现在不是鼓励而不是劝阻吗?:-)