所以我想使用 java.awt.Color的东西,我想能够编写如下代码: (use 'java.awt.Color)(= Color/BLUE (- Color/WHITE Color/RED Color/GREEN)) 看一下核心实现 – ,它具体谈到了clojure.lang.Numbers,这对我来说意味着我
(use 'java.awt.Color) (= Color/BLUE (- Color/WHITE Color/RED Color/GREEN))
看一下核心实现 – ,它具体谈到了clojure.lang.Numbers,这对我来说意味着我没有做任何事情来“勾”到核心实现中并扩展它.
在互联网上看,人们似乎有两件不同的事情:
>编写自己的defn – 函数,它只知道他们感兴趣的数据类型.为了使用你可能会在前缀命名空间,所以像:
(=颜色/蓝色(scdf.color / – 颜色/白色/红色/绿色))
或者使用命名空间,并使用clojure.core / – 当你想要数字数学.
>将一个特殊情况代码到你的 – 通过传递给clojure.core /的实现 – 当你的实现被传递一个数字.
不幸的是,我不喜欢这些.第一个可能是最干净的,因为第二个假设是你关心数学的唯一的事情是他们的新数据类型和数字.
我是Clojure的新人,但是我们不应该在这里使用Protocols或Multimethods,所以当人们创建/使用自定义类型时,他们可以“扩展”这些功能,以便他们工作无效.有没有理由, – 等不支持这个? (或者他们呢?他们似乎没有从我的代码阅读,但也许我读错了).
如果我想为其他数据类型的常用现有函数编写自己的扩展名,那么我应该怎么做,这样就可以很好地与现有的函数和潜在的其他数据类型一起使用?
基于协议(并使它们仅仅是数字的工作)在核心中进行算术运算的可能原因是性能.协议实现需要额外的查找来选择所需功能的正确实现.尽管从设计的角度来看,基于协议的实现可能会感觉很好,并且在需要的时候扩展它们,但是当你有一个紧密的循环来执行这些操作很多次(这是算术运算的常见用例),你将开始感觉性能问题是因为对在运行时发生的每个操作进行了额外的查找.如果您在自己的命名空间中为您自己的数据类型(例如:color / – )单独执行,那么由于直接调用该函数,它会更加有效,并且可以使特定情况更加明确和可定制.
这些功能的另一个问题是它们的不同性质(即它们可以采取任何数量的参数).这是提供协议实现的一个严重问题,因为协议扩展类型检查仅适用于第一个参数.