首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将状态保存在clojure上

将状态保存在clojure上
EN

Stack Overflow用户
提问于 2018-03-25 21:44:36
回答 2查看 986关注 0票数 1

我现在开始进行函数式编程,我非常喜欢没有变量的工作。

我读过的每一篇教程都说重新定义变量并不酷,但我不知道如何解决实际问题而不将状态保存在变量上。

例如:我正在处理一个API,我希望通过请求保持这些值。假设我有一个添加person的终结点,并且我有一个persons列表,我想要redefine或更改添加新personpersons列表的值。我该怎么做?

可以使用var-setalter-var-rootconj!吗?

(对于api,我使用的是compojure-api,每个person都是一个Hash)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-03-25 22:45:16

Clojure将值与标识区分开来。您可以在您的组合应用程序中使用原子来管理状态。

代码语言:javascript
复制
(def persons (atom [])) ;; init persons as empty vector
(swap! persons #(conj % {:name "John Doe"})) ;; append new value

您可以在文档中找到更多:

https://clojure.org/reference/atoms

structures

https://clojuredocs.org/clojure.core/atom

票数 6
EN

Stack Overflow用户

发布于 2018-03-25 22:44:43

在大型应用程序中,您可能需要一个可变的状态,但并不是所有情况下都需要这样的状态。

我不太熟悉概念,但这里有一个使用不变的小例子,它可能会给您一个更好的想法:

代码语言:javascript
复制
(loop [requests []
       people []

   (let [request (receive-request)]
     ; Use requests/people

     ; Then loop again with updated lists
     (recur (conj requests request)
            (conj people (make-person request))))])

这里我使用的是假设的receive-requestmake-person函数。

loop创建几个绑定,并在每个recur上更新它们。这是一种“重新定义变量”的简单方法。这与纯递归类似,在这种情况下,您不会在任何时候更改最终结果,只需更改传递给下一次迭代的值。

当然,这非常简单,而且不切实际,因为您一次只收到一个请求。如果同时接收来自多个线程的请求,对于一个原子来说,这是一个合理的案例:

代码语言:javascript
复制
(defn listen [result-atom]
  (Thread.
    (fn []
      (while true ; Infinite listener for simplicity
        (let [request (receive-request)]
          (swap! result-atom #(conj % (make-person request))))))))

(defn listen-all []
  (let [result-atom (atom [])]
    (listen result-atom)
    (listen result-atom)))
    ; result-atom now holds an updating list of people that you can do stuff with

swap!通过将原子插入到它所保存的列表上而使原子发生突变。原子内部的列表没有发生变异,它只是被修改过的自身版本所取代。任何保持对旧列表的引用的人都不会受到对swap!的调用的影响。

一种更好的方法是使用类似于core/异步的库,但这是在回避这个问题。

关键是,您可能需要在某个地方使用可变变量,但是对它们的需求要比以前少得多。在大多数情况下,几乎所有的事情都可以使用不变性来完成,就像在第一个例子中一样。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49481260

复制
相关文章

相似问题

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