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
如何解决Clojure中的“有状态问题”?_Clojure_Functional Programming - Fatal编程技术网

如何解决Clojure中的“有状态问题”?

如何解决Clojure中的“有状态问题”?,clojure,functional-programming,Clojure,Functional Programming,我是clojure的新手,我很难理解一些概念,特别是纯函数和不变性 我仍然无法理解的一件事是,在clojure中如何解决这样的问题: 一个带有登录方法的简单控制台应用程序,用户在一分钟内登录次数不能超过3次 例如,在C语言中,每次用户尝试登录时,我都可以向集合中添加UserId和时间戳,然后检查在最后一分钟内是否有超过3次的尝试 考虑到我不能改变我的收藏,在Clojure我该怎么做 这不是一个实际的问题,尽管欢迎使用一些代码示例,但我想了解如何处理这样的问题。在大多数情况下,您不会更改对象,而是

我是clojure的新手,我很难理解一些概念,特别是纯函数和不变性

我仍然无法理解的一件事是,在clojure中如何解决这样的问题:

一个带有登录方法的简单控制台应用程序,用户在一分钟内登录次数不能超过3次

例如,在C语言中,每次用户尝试登录时,我都可以向集合中添加UserId和时间戳,然后检查在最后一分钟内是否有超过3次的尝试

考虑到我不能改变我的收藏,在Clojure我该怎么做


这不是一个实际的问题,尽管欢迎使用一些代码示例,但我想了解如何处理这样的问题。

在大多数情况下,您不会更改对象,而是创建旧对象的新版本:

(loop [attempt-dates []]
  (if (login-is-correct)
    (login)
    (recur (conj attempt-dates (current-date-stamp)))))
在本例中,我使用循环。我给recur的任何东西都将传递给循环的下一个迭代。我正在创建一个新列表,其中包含在我编写conj-trument-dates当前日期戳时的新戳,然后新列表将传递给循环的下一个迭代

大多数情况下都是这样。与其考虑更改对象,不如考虑创建对象的转换副本并传递副本

如果您确实需要可变状态,那么您可以使用可变原子来保持不变状态:

(def mut-state (atom []))

(swap! mut-state conj 1)

(println @mut-state)  ; Prints [1]
[]在这里仍然是不变的,新版本只是替换可变atom容器中的旧版本


除非您需要与UI回调或类似的东西进行通信,否则通常不需要可变性。练习使用loop/recur和reduce。在大多数情况下,您不会更改对象,而是创建旧对象的新版本:

(loop [attempt-dates []]
  (if (login-is-correct)
    (login)
    (recur (conj attempt-dates (current-date-stamp)))))
在本例中,我使用循环。我给recur的任何东西都将传递给循环的下一个迭代。我正在创建一个新列表,其中包含在我编写conj-trument-dates当前日期戳时的新戳,然后新列表将传递给循环的下一个迭代

大多数情况下都是这样。与其考虑更改对象,不如考虑创建对象的转换副本并传递副本

如果您确实需要可变状态,那么您可以使用可变原子来保持不变状态:

(def mut-state (atom []))

(swap! mut-state conj 1)

(println @mut-state)  ; Prints [1]
[]在这里仍然是不变的,新版本只是替换可变atom容器中的旧版本


除非您需要与UI回调或类似的东西进行通信,否则通常不需要可变性。练习使用loop/recur和REDUCT来代替。

我认为Carcigenicate对您的具体问题有一个很好的答案。为了更全面地了解Clojure程序设计,我建议在youtube上查看Clojure-Mark Bastian中的自下而上与自上而下设计。谢谢,我一定会看一看。我检查了一些资源,但没有一个资源能够回答我的问题。为了能够给出更相关的答案,我想我需要一个更具体的例子来说明数据是如何被使用的。如果您处理的是异步代码,那么可能需要使用atom,正如我在底部所示。我认为Carcigenicate对您的具体问题有一个很好的答案。感谢你了解Clotenjure的设计,请点击查看。我检查了一些资源,但没有一个资源能够回答我的问题。为了能够给出更相关的答案,我想我需要一个更具体的例子来说明数据是如何被使用的。如果您处理的是异步代码,您可能需要使用atom,如我在底部所示。很抱歉删除了注释。起初我以为我理解了你的例子,但我没有。经过一些思考,我终于做到了。我有一个错误的想法,你的代码就像一个端点,每次用户提出新请求时,尝试日期都是空的。@M.Arkk哦,不。尝试日期在一次循环调用中的每次迭代之间传递。如果您在循环内部接受请求,那么这将起作用。如果您在别处异步接收请求,我可能会使用atom。很抱歉删除了注释。起初我以为我理解了你的例子,但我没有。经过一些思考,我终于做到了。我有一个错误的想法,你的代码就像一个端点,每次用户提出新请求时,尝试日期都是空的。@M.Arkk哦,不。尝试日期在一次循环调用中的每次迭代之间传递。如果您在循环内部接受请求,那么这将起作用。如果您在别处异步接收请求,我可能会使用atom。