Clojure的符號文字are documented需要以非數字字符開頭。這與Java標識符或數字文字語法無關--Clojure符號文字是clojure.lang.LispReader
的read
方法作爲符號讀入的內容,並且Clojure符號文字中允許使用許多字符,這些字符在Java標識符中不允許(例如-
,>
...;還有一種將這些轉換成字符序列的方案,例如用於>
的用於互操作的_GT_
)。導致錯誤的直接原因是clojure.lang.LispReader/read
在看到一個數字後立即發送到readNumber
,並且無法「退出」。
爲了完整性而進行的切題討論。
請注意,如果您構建用手一個符號,你可以用它來命名VAR:
;; Clojure's intern serves a different purpose to CL's intern, see (doc intern)
user> (intern *ns* (symbol "1+") inc)
#'user/1+
user> ((ns-resolve *ns* (symbol "1+")) 1)
2
你甚至可以做時髦的東西一樣
user> (eval `(defrecord ~(symbol "1foo") []))
user.1foo
user> user.1foo
user.1foo
user> (user.1foo.)
#:user.1foo{}
...這是當然完全是瘋狂的,雖然也許沒有那麼多
user> (in-ns (symbol "1foo"))
#<Namespace 1foo>
1foo> (clojure.core/refer-clojure)
nil
1foo> (defrecord Foo [])
1foo.Foo
1foo> (in-ns 'user)
#<Namespace user>
user> (1foo.Foo.)
; Evaluation aborted. ;; can't do that
user> (eval `(new ~(symbol "1foo.Foo")))
#:1foo.Foo{}
我想如果有人堅持要這樣做最終會碰到JVM的限制。這樣做當然沒有好的目的......無論如何,回到原來的問題,由1+
引起的錯誤與符號字面語法有關,該符號字面量語法僅對於存在合理「翻譯」的程度而言是Java友好的。有名字的Clojure對象不太關心那些名稱是否構造良好或其他,儘管使用時髦的名字是笨拙的,絕對不支持。
(而user.1foo
從上面的例子實際上是一個Java類 - 我有點驚訝地看到,這其中有實際工作,但在另一方面,我好像記得JVM內部的限制上的名字都應該比起Java那些要嚴格得多)
請注意,在Common Lisp中,一致性實現可能會將'1a'解析爲數字,就像Clojure試圖(甚至沒有* * read-base *比10)。請參閱HyperSpec中潛在編號的條目:http://www.lispworks.com/documentation/HyperSpec/Body/02_caa.htm – 2010-08-02 14:57:45