Clojure 伪装为泛型超类/接口的协议调用函数?
例如: 如果呼叫Clojure 伪装为泛型超类/接口的协议调用函数?,clojure,Clojure,例如: 如果呼叫 (defprotocol P (foo [x]) (bar [x])) (extend-protocol P Superclass ;; a java abstract class (foo [x] (println "superclass")) Subclass ;; a concrete java class implementing the above abstract class (foo [x] (foo (cast S
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Superclass ;; a java abstract class
(foo [x]
(println "superclass"))
Subclass ;; a concrete java class implementing the above abstract class
(foo [x]
(foo (cast Superclass x))))
很明显,我会得到堆栈溢出,但是有没有什么方法可以完成我在这里尝试做的事情,即调用与泛型超类/接口相同的函数,但伪装成泛型超类/接口
更新:一个更清晰的示例演示了我所问问题的用例:
(foo subclass-instance)
cast
的问题在于,它的工作方式类似于类型断言
,如果对象不满足is-a关系,则只会抛出异常
(defprotocol P
(extract-properties-into-map [self]))
(extend-protocol P
PropertyContainer ;; abstract class
(extract-properties-into-map
[this]
(into {} (for [[k v] (.getProperties this)] [(keyword k) (read-string v)])))
Foo
(extract-properties-into-map
[this]
(assoc {:properties (extract-properties-into-map
^PropertyContainer this)} ;; this is where it falls apart
:foo-type (.getFooType this)
:foo-permissions (.getPermissions this)
:foo-whatever (.getWhatever this))))
在不同的函数中没有返回到分派的新接口,即堆栈溢出
我不确定为
接口扩展协议意味着什么?由于您提供的是一个实现,我想您应该首先定义一个类型
,并在该超级类型上扩展协议。编辑:基于
打电话给
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Number ;; a java abstract class
(foo [x]
(println "superclass:" x))
Integer ;; a concrete java class implementing the above abstract class
(foo [x]
(foo (delegating-proxy x [Number] []))))
虽然它按照问题的要求执行,但现在它包装了原始的x
。根据需求,最好将foo
委托给协议中未包含的函数,可能是superfoo
(foo (Integer. 1))
=> superclass: 1
我认为根本的问题是协议不知道类继承。此外,Clojure似乎应该等待将对象强制为类型。类型提示在这种情况下不起作用。是超类和子类记录还是Java类?@Jared314 Java类。我刚刚编辑了这个问题以反映这一点。谢谢,谢谢。是的,问题出在原来的x上。
(foo (Integer. 1))
=> superclass: 1
(defn superfoo [x] { :byte (.byteValue x) })
(defprotocol P
(foo [x])
(bar [x]))
(extend-protocol P
Number ;; a java abstract class
(foo [x]
(superfoo x))
Integer ;; a concrete java class implementing the above abstract class
(foo [x]
(merge (superfoo x) { :f (.floatValue x)})))