在clojurescript中通过deftype创建类型时:
(deftype SomeObject [a b c]
Object
(update [_]
(set! (.-a _) 5)
(set! (.-b _) 6) ))
是否有可能扩展构造函数?我想在创建对象时对其进行一些初始化!
答案 0 :(得分:3)
在deftype
中没有支持,没有; Clojure(Script)等效于定义工厂函数,可能是make-some-object
,并使用它而不是实际的构造函数。有关示例和基本原理,请参阅amalloy的答案。
当然在JavaScript中,构造函数只是函数,您当然可以使用ClojureScript定义一个函数,该函数将作为JS构造函数使用:
;; "constructor" with default field values
(defn Point [x y]
(this-as this
(set! (.-x this) (if x x 10)) ; NB. Clojure truth semantics are used
(set! (.-y this) (if y y 20))))
(.-x (Point. 2))
;= 2
(.-y (Point. 2))
;= 20
这有点违背语言的整体精神,除非在特殊情况下,否则不可取。 (与期望构造函数作为参数的JS API互操作?)
答案 1 :(得分:2)
deftype的构造函数是故意简约的:它只复制N个对象来保存数据字段。没有必要让它更强大,因为你已经有了一个工具来完成这项工作:只需要简单的旧功能。
(defn foo [opts]
(if-not (acceptable? opts)
(throw (Exception. "No way, man"))
(Foo. (:x opts) (:y opts)))
是包装deftype构造函数的简单示例。即使deftype允许你用这种逻辑灌输“真正的”构造函数,在客户端API和底层表示之间创建一个抽象屏障也是很好的,这样如果表示发生变化,客户端代码可能主要不受影响。
答案 2 :(得分:0)
谢谢大家,我会选择工厂方法。无论如何,可能在ClojureScript中最有意义!我想我将来会尝试避免使用deftypes / Types,因此工厂方法可以很好地隐藏它。仍处于功能编程的过渡阶段;)