2010-09-20 57 views
1

此问题与this one密切相关,但我认为更一般。我们如何能够即时创建某个类型或记录的“实例”

最近我尝试使用multimethods(或使用独特的函数构造函数,如果可能)创建类型“实例”,基于元数据标记。我用这个标签链接了一个类型(引擎盖下的java类),然后我不知道如何以优雅的方式继续(没有eval或java反射和字符串);新是一种特殊的形式,虽然使用宏,但很难处理。

在seudo代码将是:

(def my-tagged-data (with-meta my-data {:my-type-tag my-ns.My-Type})) 
(def factory-function [tagged-data] 
    (create (:my-type-tag (meta tagged-data)) tagged-data)) 
+0

重新阅读引用的上一个问题的评论可能唯一的方法是修改clojure的数据类型功能: -/ – jneira 2010-09-20 08:24:23

+0

是否要为每种记录类型编写自定义工厂代码并以某种方式将其与记录类型相关联,以便您可以使用记录类型的名称(而不是工厂名称)调用工厂? – Chouser 2010-09-20 14:38:59

+0

mmm这正是mi原来的想法,如果可能,没有明确的工厂,使用多方法或协议方法(或有点派遣)以可扩展的方式添加构造函数 – jneira 2010-09-20 16:20:27

回答

2

您可以为您的类型提供工厂函数。

(def my-tagged-data (with-meta my-data {:my-type-factory `my-type-factory})) 

(defn factory-function 
    [tagged-data] 
    (@(resolve (:my-type-factory (meta tagged-data))) tagged-data)) 

这可能也可能不可行。

+0

是@解决我的未知错字或黑客?我没有注意解决,感谢这一点。 – jneira 2010-09-20 12:39:56

+0

@是dereffing由解析返回的var,但在这种情况下是可选的,因为您可以直接调用var。 – cgrand 2010-09-20 13:22:56

+0

kotarak的想法很好,但没有象征符号,您可以直接将工厂放入元数据中,并使用全局注册表作为遗留类的后备。 – cgrand 2010-09-20 13:27:01

0

我认为你必须使用反射。 (我认为比eval更好的想法)。

+0

此外,我缺少一些明显的原因,我不知道如何使用newInstance ,导致整数/类别都不工作(整数/ newInstance) – jneira 2010-09-20 11:44:46

相关问题