2010-05-14 66 views
1

在我的列表中,另外,操作+显示为#。我怎样才能让它看起来完全符合+?当我评估它时,它也应该和+完全一样。如何重命名Clojure中的操作?

我想这也适用于Clojure的各种功能... 谢谢你们。

回答

1

操作只是一段代码,分配给一个变量。如果你想重新绑定操作,您只需重新绑定变量:

(def - +) 
(- 1 2 3) 
# => 6 

这里唯一的问题是,#字符是用Clojure特殊。我不知道你是否能在所有使用#作为变量名,至少是结合它的时候,也许你也将需要引用它,当调用它:

(def # +) 
# => java.lang.Exception: No dispatch macro for: 

不幸的是,我我不熟悉Clojure知道如何引用它。

+1

实际上,在Clojure 1.1中,重新定义从其他命名空间引用Vars的名称并不那么简单。例如。 '(def - +)'通常在1.1 REPL中导致以下结果:'java.lang.Exception:名称冲突,无法def - 因为namespace:user引用:#'clojure.core/- (NO_SOURCE_FILE:1) '。请参阅我的答案以获得解决方法。这可能会在Clojure 1.2中改变。 – 2010-05-14 12:37:00

+0

@MichałMarczyk:谢谢你的纠正。我实际上并不知道任何Clojure。我只是打开了* REPLs的主*,输入并运行。不知道他们使用的是什么版本。 – 2010-05-14 15:25:46

+0

LotREPLs ... 8-O哇,谢谢你提到这个!另外,很高兴在Clojure标签上见到你,我相当喜欢你的答案。 :-) – 2010-05-14 23:19:56

5

#人物根本就不是在用Clojure(见this page为有效字符列表),虽然它可能工作有时符号名有效字符(因为它往往会),它不使用它一个很好的做法。另外,它肯定不会在符号(实际上是一个文字,你仍然可以做(symbol "#"),尽管这可能没有意义)的开始工作。正如Clojure读者目前所看到的那样,除此之外没有任何可以做的事情(除非可能会破坏读者对它的看法#(即'#'后面跟一个空格)作为符号# - 或者简单地+--尽管这是某种东西你真的不应该这样做,所以我几乎对提供a link关于如何去做的说明感到内疚)。

如果您想将名称别名为Clojure中合法的其他名称,您可能会发现使用clojure.contrib.def/defalias宏而不是普通的def方便;这为您设置元数据提供了额外的好处(并且应该处理宏,虽然它似乎有一个可以防止此时的错误,至少在1.2 HEAD中)。


而如果你想创建别名时......重新定义一些内置的名字(如果你不这样做,这剩下的可能不是与你有关的。)

首先,如果您使用Clojure 1.1或更早的版本,并且您想为自己的绑定提供clojure.core的名称,则在定义名称空间时需要使用:refer-clojure。例如。如果你想提供自己的+

(ns foo.bar 
    (:refer-clojure :exclude [+])) 

;; you can now define your own + 
(defn + [x y] 
    (if (zero? y) 
    x 
    (recur (inc x) (dec y)))) 

;; examples 
(+ 3 5) 
; => 8 
(+ 3 -1) 
; => infinite loop 
(clojure.core/+ 3 -1) 
; => 2 

需要这个来自Clojure的1.1导致禁止其指瓦尔其他命名空间名称的重新绑定; ns-unmap提供了一种适合REPL使用的方法,而(:refer-clojure :exclude ...),(:use :exclude ...)(:use :only ...)系统地提供了防止不必要的名称从其他名称空间导入的方法。

在当前的1.2个快照中,有一个“最后一个var-in wins”策略,所以你可以不用:refer-clojure;但它仍然会生成编译器警告,使用:refer-clojure的样式会更好,并且不能保证此策略在实际的1.2版本中能够存活。