Clojure最佳实践:何时使用元数据?

12
我不是在主观提问,而是想了解为什么语言中确切地有with-meta。我意识到它可以用于许多目的(就像eval一样,但其在特定情况下以外的使用是设计不良的标志)。从设计角度来看,Clojure的元数据结构有什么独特的作用?它主要用于文档吗?这是一种简写方式吗? with-meta/meta有哪些强大的应用?在哪些情况下使用它是不合适的?您能否举一个使用元数据完成某些不可能/困难/繁琐的任务的示例?
3个回答

7

该语言的几个核心特性依赖于元数据:

  • macros one feature that depends on metadata. A macro is a function with a bit of metadata that causes the function to run at compiletime.

    user> (meta #'when)
    
    {:macro true, 
     :ns #<Namespace clojure.core>, 
     :name when, :arglists ([test & body]), 
     :column 1, :added "1.0", 
     :doc "Evaluates test. If logical true, evaluates body in an implicit do.", 
     :line 471, 
     :file "clojure/core.clj"}
    
  • Types are another feature of the language that depends on metadata. The type of something is expressed as metadata on that object.

  • tests also use metadata. when you (or lein) call run-tests it looks at the metadata on the functions in each namespace to find the ones that are tests.

有很多案例涉及到语言核心,如类型,以及像n-repl/cider这样的外围事物,在你工作时在屏幕底部显示函数参数,都使用了元数据。只要不用它做丑陋的事情,使用元数据并不是设计上的问题;)


有人知道如何使代码在项目符号列表中以正确的代码块形式显示出来吗? - Arthur Ulfeldt
您必须使用4个空格进行缩进,并在项目符号文字和代码之间放置空行。 - danneu
7
尊敬的@ArthurUlfeldt,这个答案有点空洞!请告诉我那些丑陋的事情? - Alister Lee

2
元数据对于给不需要直接附加细节的值附加细节非常有用。例如,在Web服务器中,您可以使用元数据来附加有关函数端点信息的详细信息(例如,调用此函数是否需要身份验证),并在处理程序中处理它们。例如,Ring 使用元数据来检查是否应重新创建会话。

1
除了Arthur Ulfeldt上面提到的内容之外,Clojure的一个独特特点是使用元数据来扩展协议。这允许您在创建对象(实际上是任何值)后动态地将协议添加到几乎任何对象中。据我所知,大多数其他语言都没有这种能力(Smalltalk可能是一个例外)。
有关更多信息,请参见通过元数据扩展
由于在Clojure中添加元数据不会影响相等语义,因此如果添加元数据导致应用程序错误地将两个对象视为相等,则可能会遇到语义问题。这个问题是特定于领域的。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接