Types clojure扩展类型vs deftype和协议实现

Types clojure扩展类型vs deftype和协议实现,types,clojure,extend,Types,Clojure,Extend,书中有这样一段话: 我们需要这样定义所有的类型: (deftype AllType[]) 最后,我们需要添加AllType select的实现* (extend-type AllType Navigator (select* [this structure continuation] ...)) (如果您精通协议,您可能想知道为什么在定义类型时不定义select*: (deftype AllType [] Navigator (select* [this structu

书中有这样一段话:

我们需要这样定义所有的类型:

(deftype AllType[])

最后,我们需要添加AllType select的实现*

(extend-type AllType   Navigator   (select*
[this structure continuation]
    ...))
(如果您精通协议,您可能想知道为什么在定义类型时不定义select*:

(deftype AllType []
  Navigator
  (select* [this structure continuation]
    ...))

原因是特定协议函数的依赖于实现的查找对于以这种方式定义的函数不起作用。)

我真的不明白作者想说什么。
extend type
deftype
+就地实现之间有什么区别

我刚读完上一章中讨论过的内容。您可能希望在那里查看更多详细信息

其要点是,它们在概念上似乎相同,但事实并非如此。 他描述了语义“gotcha”,因为Java类也定义了名称空间。例如:

(ns my.ns)
(defprotocol Foo  (run [this]))

(ns your.ns)
(defprotocol Foo  (run [this]))

(ns user)
(defrecord FooAble [])
(extend-protocol my.ns/Foo
  FooAble
  (run [this] (println "Foo Me")))
(extend-protocol your.ns/Foo
  FooAble
  (run [this] (println "Foo You")))

(println 1 (->FooAble))
(def some-foo (->FooAble))

(my.ns/run   some-foo)  => Foo Me
(your.ns/run some-foo)  => Foo You
在Java中,您会尝试说

someFoo.run()  =>  Which `run` method...?
因此,在Clojure中,我可以在一个对象上运行两个同名签名的
方法iff我使用
扩展协议
。如果我试图定义内联it崩溃:

(defrecord BeerAble []
  my.ns/Beer
  (run [this] (println "Beer Me"))
  your.ns/Beer
  (run [this] (println "Beer You")))

(println 2 (->BeerAble))
(def some-beer (->BeerAble))

(my.ns/run   some-beer)
(your.ns/run some-beer)

;=>  CompilerException java.lang.ClassFormatError: Duplicate method name&signature in class file user/BeerAble,
因此,内联定义就像试图用两个
void run()
方法创建一个Java接口。要使其正常工作,您必须将方法名称更改为
myRun
yourRun
,如果两个外部lib已经选择了函数名
run
,并且现在发生冲突,那么这充其量是不可能的


由于没有读过《幽灵》这本书,我不能说这是否直接回答了最初的问题,但你可能希望做一点实验。除非您有名称空间/函数冲突的问题,否则无论哪种方式,您都应该得到相同的结果。您还可以分析您的程序,以确定其中一个是否加快了您的程序


现在更仔细地看文本,我看不出它对他引用的用例有什么影响。您可以尝试验证答案。

电子书链接不起作用。@AlanThompson谢谢,更正。“原因是特定协议函数的依赖于实现的查找对以这种方式定义的函数不起作用。”对我来说没有任何意义。它们在实现方式上是不同的,但我一点也不清楚所描述的区别是什么。