_评论由: mfikes_
我在定义应该发生什么的问题上有些困扰,而且在我缺乏明确性的核心是,是否{{my.ns/A}}是一个Var还是仅仅是一个类型。
在编译器状态下,它确实显示在{{:defs}}下,但被标记为{{:type true}}。换句话说,仅仅因为它在{{:def}}下并不表示它是一个Var。在Clojure中,即使存在可以通过.Interop访问的底层构造函数,但并没有创建实际的Var。(支持这一说法的证据是,{{(var A)}}在Clojure中失败,如果在REPL中使用{{dir}}则不会出现Var——你只能看到相关的合成位置和映射工厂Var)。
"它不是一个Var"的另一个论点是{{defrecord}}返回的结果。{{defrecord}}不返回Var(即使在Clojure中),而是返回一个符号(它相当于自己,就像符号{{java.lang.String}})。
如果你同意底层构造函数不是一个Var的论点,那么可能需要清理一些事情(修复ClojureScript中的{{dir}},以及可能如果{{var}}应用到类型上导致其拒绝)。
此外,如果你同意它不是一个Var的论点,那么你可能认为{{import}}是合适的,而{{require}}则不适合。受到
http://puredanger.github.io/tech.puredanger.com/2010/06/30/using-records-from-a-different-namespace-in-clojure/的启发,这种变化似乎运行良好
(ns my.ns)
(defrecord A [foo bar])
(ns other.ns
(:require [my.ns])
(:import (my.ns.A)))
(println (my.ns.A. 1 2) (my.ns/->A 1 2))
(defrecord A [baz quux])
(println (my.ns.A. 1 2) (my.ns/->A 1 2))
(println (A. 3 4) (->A 3 4))
结果是
cljs.user=> (require 'other.ns)
#my.ns.A{:foo 1, :bar 2} #my.ns.A{:foo 1, :bar 2}
#my.ns.A{:foo 1, :bar 2} #my.ns.A{:foo 1, :bar 2}
#other.ns.A{:baz 3, :quux 4} #other.ns.A{:baz 3, :quux 4}
nil
我不喜欢的一点是,你必须写{{(:import (my.ns.A))}}而不是{{(:import (my.ns A))},但这可能是"不是一个Var"方法中的一个小问题。