所以我认为命名一个计算指数^
的函数是一个不错的主意,但看起来插入符实际上做了一些特殊的事情,因为Clojure REPL在评估{{1}时会产生错误}。谷歌搜索主要给了我this,所以我想知道Clojure中插入符号的实际用途是什么。
(另外,是否可以命名一个函数'^
?)
答案 0 :(得分:40)
^
是“元字符”,它告诉the reader将以^
开头的符号作为元数据添加到下一个符号(假设它是实现IMetas的东西)
user=> (def x ^:IamMeta [1 2 3])
#'user/x
user=> x
[1 2 3]
user=> (meta x)
{:tag :IamMeta}
user=>
通过查看事物的meta
,您可以了解很多关于clojure如何工作的知识,例如函数:
user=> (meta foo)
{:ns #<Namespace user>,
:name foo, :file "NO_SOURCE_PATH",
:line 5, :arglists ([s])}
这经常用于type hints
(defn foo [^String s] (.charAt s 1))
通常最好打开反射警告(set! *warn-on-reflection* true)
,然后添加类型提示,直到警告消失为止。如果没有这些Clojure,它会在运行时查找函数操作数的类型,这样可以节省大量类型的烦恼。
PS:我的下一个最喜欢的读者角色是“发送”角色#
,下一步值得学习:)
PPS:这在clojure 1.2.x vs clojure 1.3.x中有所不同 在Clojure 1.2.1中,当您使用元字符时,元数据不会组成:
user=> (def foo ^:foo ^:bar [1 2 3])
#'user/foo
user=> (meta foo)
{:tag :foo}
并且在1.3中它“做正确的事”并且关键字也是选项而不是“标签”:
user=> (def foo ^:foo ^:bar [1 2 3])
#'user/foo
user=> (meta foo)
{:foo true, :bar true}
答案 1 :(得分:0)
在我看来,不幸的是,你的问题的答案是否定的。在Clojure中,您不能将函数命名为^
。
我在REPL中尝试了以下内容:
user=> (println \^)
^
nil
这似乎暗示你可以用反斜杠逃脱克拉(^
)。但是,如果我尝试使用\^
作为名称声明一个函数,那么我会收到一条错误消息:
user=> (defn \^ [n e] (cond (= e 0) 1 :else (* n (\^ n (- e 1)))))
IllegalArgumentException First argument to defn must be a symbol
clojure.core/defn (core.clj:277)
相同的代码使用常规文本名称:
user=> (defn exp [n e] (cond (= e 0) 1 :else (* n (exp n (- e 1)))))
#'user/exp
user=> (exp 3 3)
27
如果有一个比我更好的Clojure-fu的人可以证明我错了,我会很高兴的! :)