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_Macros - Fatal编程技术网

通过宏将名称空间函数收集到映射中是否是Clojure的惯用方法?

通过宏将名称空间函数收集到映射中是否是Clojure的惯用方法?,clojure,macros,Clojure,Macros,我正在通过一个宠物项目学习Clojure。该项目将由其他职能部门调用的几个工人组成 每个worker在其自己的命名空间中定义为一组函数,目前有两个:获取用于收集数据的数据和写入用于将收集的数据写入文件的数据 为了使代码更简洁,我决定编写一个宏,将命名空间中的函数收集到一个可以传递的映射中: (ns clojure-bgproc.workers) (defmacro gen-worker-info [] (let [get-data (ns-resolve *ns* 'get-data)

我正在通过一个宠物项目学习Clojure。该项目将由其他职能部门调用的几个工人组成

每个worker在其自己的命名空间中定义为一组函数,目前有两个:获取用于收集数据的数据和写入用于将收集的数据写入文件的数据

为了使代码更简洁,我决定编写一个宏,将命名空间中的函数收集到一个可以传递的映射中:

(ns clojure-bgproc.workers)

(defmacro gen-worker-info []
  (let [get-data (ns-resolve *ns* 'get-data)
        write-data (ns-resolve *ns* 'write-data)]
    `(def ~(quote worker-info)
       {:get-data ~get-data
        :write-data ~write-data}
       )
    )
  )
在我的工作者代码中,为了清晰起见,我使用了经过删节的宏代码:

(ns clojure-bgproc.workers.summary
  (:require [clojure-bgproc.workers :refer [gen-worker-info]]))

(defn get-data [params]
  <...>
  )

(defn write-data [data file]
  ;; <...>
  )

(gen-worker-info)
虽然它确实起作用,但我在clojure-bgproc.workers.summary/worker-info中获取get data和写入data函数,我发现它有点令人讨厌,特别是因为如果我将宏调用移到文件顶部,它就不起作用了

我的问题是,有没有更惯用的方法?这是一个地道的Clojure吗


谢谢。

我定义worker的解决方案是协议。我还将应用一些久经考验的系统生命周期管理框架

提供一种定义一组方法及其签名的方法。您可能认为它们类似于面向对象编程中的接口,但比面向对象编程中的接口更灵活

您的工作人员可能有一些状态和生命周期,例如,工作人员可能正在运行或停止,获取和释放资源,等等。我建议您考虑一下如何使用有状态组件(即工人)管理系统


在这种情况下,我主张避免使用宏。这句格言似乎适用于这里。宏在运行时不可用,这使得调试更加困难,并迫使所有查看您的代码的其他程序员学习新的特定于域的语言,即使用宏定义的语言

我定义工人的首选解决方案是协议。我还将应用一些久经考验的系统生命周期管理框架

提供一种定义一组方法及其签名的方法。您可能认为它们类似于面向对象编程中的接口,但比面向对象编程中的接口更灵活

您的工作人员可能有一些状态和生命周期,例如,工作人员可能正在运行或停止,获取和释放资源,等等。我建议您考虑一下如何使用有状态组件(即工人)管理系统


在这种情况下,我主张避免使用宏。这句格言似乎适用于这里。宏在运行时不可用,这使得调试更加困难,并迫使所有查看您的代码的其他程序员学习新的特定于域的语言,即使用宏定义的语言

我认为你处于一个奇怪的位置,因为你的程序结构错误:

每个worker在其自己的命名空间中定义为一组函数

这才是真正的问题。名称空间是放置函数和值的好地方,您将在手写代码中引用这些函数和值。对于您希望以编程方式访问的内容,它们不是一个好的存储空间。相反,通过将要访问的数据放入普通的适当数据结构中,使其成为一流的数据,这样就很容易操作


例如,您正在考虑从名称空间派生的worker信息映射非常棒!事实上,这应该是表示worker的唯一方式:作为带有worker函数键的映射。然后你只需要在某个地方定义一个列表或向量,或者这样的工作者映射的映射,这就是你的工作者列表。不要乱搞所需的名称空间。

我认为您处于一个奇怪的位置,因为您的程序结构错误:

每个worker在其自己的命名空间中定义为一组函数

这才是真正的问题。名称空间是放置函数和值的好地方,您将在手写代码中引用这些函数和值。对于您希望以编程方式访问的内容,它们不是一个好的存储空间。相反,通过将要访问的数据放入普通的适当数据结构中,使其成为一流的数据,这样就很容易操作


例如,您正在考虑从名称空间派生的worker信息映射非常棒!事实上,这应该是表示worker的唯一方式:作为带有worker函数键的映射。然后你只需要在某个地方定义一个列表或向量,或者这样的工作者映射的映射,这就是你的工作者列表。不要乱动名称空间。

这可能更适合Ohh,好的,谢谢!可以在那里交叉张贴吗?或者我应该先删除这个问题吗?这可能更适合哦,好的,谢谢!可以在那里交叉张贴吗?还是我应该先删除这个问题?