这是一个稍微有些牵强的例子,但存在一个可能导致或可能不是错误的行为。
假设您有一个以下协议
(defprotocol P (f [this]))
具有可变参数和锁的实体类型
(deftype T [^:volatile-mutable x lock]
P
(f [this]
(locking lock
(set! x true)
(prn ""))))
编译器对这个没有问题。但将(prn "")
语句移出(locking …)
块外,您会得到
(deftype T [^:volatile-mutable x lock]
P
(f [this]
(locking lock
(set! x true))
(prn "")))
Syntax error (IllegalArgumentException) compiling fn* at (REPL:4:5).
Cannot assign to non-mutable: x
David Miller在最新的ClojureCLR中发现了这个行为(见https://clojure.atlassian.net/browse/CLJCLR-122),并在自己的端上寻找线索,但同样错误在JVM Clojure中提出,这表明Clojure自身中可能有一个错误,或者存在一些高度反直觉的规则在起作用,这方面的细节可能值得理解。为什么编译器会在这里将x视为不可变的尚不清楚。