2010-05-14 41 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版本中能夠存活。