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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/EmptyTag/131.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 只编写一个将给定对象保存到sqlite的函数_Clojure - Fatal编程技术网

Clojure 只编写一个将给定对象保存到sqlite的函数

Clojure 只编写一个将给定对象保存到sqlite的函数,clojure,Clojure,我只是从clojure开始,一直在思考如何实现看似简单的功能 有一个函数generator,它将saver函数作为参数。generator执行各种操作并定期生成某些需要保存的数据对象。这个保存应该由saver函数来处理,因此生成器在每次生成数据时都会调用saver,其中包含需要保存的数据 现在,我要编写的一个保存函数是将数据保存到sqlite db的。我该怎么做 我想到的一个策略是在saver函数中创建到sqlite db的连接。每次保存数据时创建一个新连接,保存数据(一个表中只有一行)并关闭

我只是从clojure开始,一直在思考如何实现看似简单的功能

有一个函数
generator
,它将
saver
函数作为参数。
generator
执行各种操作并定期生成某些需要保存的数据对象。这个保存应该由
saver
函数来处理,因此
生成器
在每次生成数据时都会调用
saver
,其中包含需要保存的数据

现在,我要编写的一个保存函数是将数据保存到sqlite db的。我该怎么做

  • 我想到的一个策略是在
    saver
    函数中创建到sqlite db的连接。每次保存数据时创建一个新连接,保存数据(一个表中只有一行)并关闭连接。这似乎有点低效。特别是考虑到数据每2-5秒生成一次

  • 另一个想法是作为模块级变量保持开放连接,在开始时设置为
    nil
    。第一次调用
    saver
    函数时会打开连接,并在后续调用中重复使用。这似乎更有效,但据我所知,它需要
    saver
    函数中的
    def
    表单。就我个人而言,我不喜欢这样做

  • 还有一个(疯狂的?)想法是使用代理保存连接对象,最初设置为
    nil
    saver
    将是一个向代理发送
    数据的函数。代理,在第一次需要时创建连接,并保存在关联的数据对象中。这看起来可能很有效,但代理不是为此而设计的,是吗

那个么,你们如何解决这个问题呢?有没有其他模式适合这种情况?或者我应该做上面的一个


另外,我花了很多时间写这篇文章,因为很难用语言表达我的问题。我不确定我是否弄对了。如果有不清楚的地方,请告诉我。

您的第二个解决方案听起来最好。如果您不想使用可变的
Var
(通过
def
创建),那么您可以在“工厂”函数中创建连接,作为一个简单的不可变值(因此它只是在闭包中携带):


免责声明:我不是伟大的clojure专家-以上是我在几乎任何函数式语言中都会这样做的。因此,也许有一种更为惯用的clojure方法。

您知道如何关闭连接吗?或者这不重要——它可以继续出现吗?现在对我来说,这并不重要,但我愿意相信,当我的应用程序关闭时,jvm会优雅地关闭它。此外,在应用程序的整个生命周期中,我都需要连接。我认为在函数中使用def表单无法解决您的问题。def表单定义了一个不可变的绑定,而不管def是在哪里定义的。您不能使用def来表示“如果此值为null,请将其设置为非null,否则使用当前值。”据我所知,没有不可变绑定。您可以任意多次
def
和重新
def
变量,尽管不鼓励这样做。绑定到变量的东西不是不可变的,创建的对象本身是不可变的。另外,
def
表单在函数内部工作。当然,我希望clojure有更好的人来证实我所说的:)闭包。我怎么没想到呢!这太棒了。这正是我需要的解决方案。但正如你所说的,我愿意看到一个clojure式的方法,如果不同的话+1.如果没有人击败我,我会建议关闭。虽然使用代理序列化您的写入可能是一件好事,但如果您不介意让它们发生在后台,那么结合起来可能会更好。是的,我同意它发生在后台。但是
代理的这个用例
不涉及代理的数据对象的任何突变。所以,我觉得代理对我想要实现的目标来说是太过了。然而,我喜欢让它在幕后发生的前景。比如
(.start(Thread.saver fn))
,或者有更好的方法吗?
(defn sqlite-saver-factory [path]
  (let [db-connection (open-sqlite-connection path)]
    (fn [data]
      (save-to-sqlite db-connection data))))
...
(generator (sqlite-saver-factory path) ...)