2

在 clojurescript 中通过 deftype 创建类型时:

(deftype SomeObject [a b c]
    Object
        (update [_]
            (set! (.-a _) 5)
            (set! (.-b _) 6) ))

是否有可能扩展构造函数?我想在创建对象时对其进行一些初始化!

4

3 回答 3

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 互操作?)

于 2013-05-18T09:20:40.430 回答
2

deftype 的构造函数有意简约:它只是复制 N 个对象来保存您的数据字段。没有必要让它更强大,因为你已经有了一个工具来完成这项工作:你只需要简单的旧函数。

(defn foo [opts]
  (if-not (acceptable? opts) 
    (throw (Exception. "No way, man"))
    (Foo. (:x opts) (:y opts)))

是包装 deftype 构造函数的简单示例。即使 deftype 允许您为“真实”构造函数注入这种逻辑,在客户端 API 和底层表示之间创建一个抽象屏障也是很好的,这样如果表示发生变化,客户端代码基本上不会受到影响。

于 2013-05-18T09:05:03.530 回答
0

谢谢大家,那我将使用工厂方法。无论如何,可能在 ClojureScript 中最有意义!我想我以后会尽量避免使用 deftypes/Types,所以工厂方法可以很好地隐藏它。仍处于向函数式编程的过渡阶段;)

于 2013-05-20T02:07:18.433 回答