groovy - Clojure 协议(protocol)和 Groovy 类别之间的区别

标签 groovy clojure protocols categories

最近看到了 Clojure 协议(protocol)的演示文稿,我对通过这种方式扩展现有类型的简洁方式印象深刻。
但是,我很确定已经在其他语言中看到过类似的方法,过了一段时间我发现它是 Groovy 类别。

比较一下:

 @Category(String) ​class StringCategory {
   String lower() {
     return this.toLowerCase()
   }
 }

 use (StringCategory) {
   println("TeSt".lower())
   assert "test" == "TeSt".lower()
 }

与 Clojure 协议(protocol)等效(取自 mikera's answer below and tested in ideone.com )
 (defprotocol Lowerable
   (lower [x]))

 (extend-protocol Lowerable
   String
     (lower [s] 
       (.toLowerCase s)))

 (println (lower "HELLO"))

我的问题是:
  • 除了性能差异(据说 Clojure 在这方面进行了高度优化) - 这两种方法之间是否存在语义差异?
  • 除了笨拙的语法之外,Groovy 方法在逻辑上还有什么问题吗?

  • 免责声明:我是一个完整的 Clojure 新手!

    最佳答案

    这是使用协议(protocol)的粗略等效 Clojure 代码:

    (defprotocol Lowerable
      (lower [x]))
    
    (extend-protocol Lowerable
      String
        (lower [s] 
          (.toLowerCase s)))
    
    (lower "HELLO")
    => "hello"
    

    关于 Clojure 协议(protocol)的主要区别(我相信这使它与 Groovy 类别版本不同)
  • Clojure 协议(protocol)定义不包含任何实现(在这方面它更像是一个接口(interface))。实现是单独提供的:您可以将 Lowerable 协议(protocol)扩展到任意数量的不同类,而无需对类本身或协议(protocol)定义进行任何更改。例如,您可以定义 lowerRope 上工作.
  • 上面的 Groovy 类别专门用于字符串 - Clojure 协议(protocol)并非如此。在这个例子中,Clojure 协议(protocol)“Lowerable”的定义没有说明参数的类型。
  • lower是适当的一等函数。因此,您可以使用它来构建更高阶的抽象(通过更高阶的函数),这反过来将接受任何已扩展 Lowerable 协议(protocol)的参数。
  • Clojure 协议(protocol)经过大量优化,因为它们旨在利用 JVM 的快速方法分派(dispatch)。因此,它们被编译成非常高效的代码(不需要动态对象检查或反射)

  • Clojure 协议(protocol)实际上是一个相当独特的 solution to the Expression Problem (链接的视频很有趣)。我认为与另一种语言中的 Clojure 协议(protocol)最接近的等价物实际上是 Haskell 类型的类。即使这样也有点牵强,因为 Haskell 是静态类型的,而 Clojure 是动态类型的......

    关于groovy - Clojure 协议(protocol)和 Groovy 类别之间的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9935186/

    相关文章:

    groovy - Gradle依赖性和路径空间

    maven - 使用gradle构建distZip/Pkg

    java - 通过Groovy脚本从 Artifactory 获取用于多个作业的最新内部版本号。

    clojure - 为什么 Clojure 的 core.reducers 比惰性集合函数更快

    ftp - 文件传输协议(protocol)选项?

    c - Wireshark - 以编程方式修改 pcap 文件中的数据包

    java - 编写依赖于 Groovy 的库是个好主意吗?

    windows-8 - Sublime Text、SublimeREPL、Clojure 和 Windows 8

    clojure - 是否可以将 Clojure 的案例形式与 Java 枚举一起使用?

    networking - 如何在 CoAP 一致性测试套件中对测试用例进行分组