【发布时间】:2015-03-23 17:41:02
【问题描述】:
Meikel Brandmeyer 在dispatch in Clojure 上写了一篇文章,URL 标题为静态与动态。他写道:
协议并不是我们在静态与动态之间进行权衡的唯一地方。有几个地方可以发现这种权衡。
他在一个协议中提供了以下静态调度的例子:
(defprotocol Flipable
(flip [thing]))
(defrecord Left [x])
(defrecord Right [x])
(extend-protocol Flipable
Left
(flip [this] (Right. (:x this)))
Right
(flip [this] (Left. (:x this))))
现在确实每个记录都映射到编译的 JVM 上的一个“类”。如果您尝试发送除Left 或Right 以外的任何内容,您将获得java.lang.IllegalArgumentException 和No implementation of method:...found for class:...。
我问是因为我的理解是 Clojure 在幕后有效地使用相同的 JVM 技术进行多态调度。我们可以将上面的内容改写为:
interface Flippable {
Flippable flip();
}
class Left implements Flippable {
Right flip();
}
class Right implements Flippable {
Left flip();
}
class Demo {
public static void main(String args[]) {
Flippable flippable = new Right();
System.out.println(flippable.flip);
}
}
现在,虽然类型被编译和静态检查,但实际的调度是在运行时进行的。
我的问题是:在 Clojure 中使用协议将调度描述为“静态”是否准确?(假设您没有使用地图进行调度,而是依赖于记录或类型对应一个类)。
【问题讨论】:
标签: interface clojure static protocols dispatch