以下示例中所示,协议方法似乎并不是直接链接的。
$ clj -J-Dclojure.compiler.direct-linking=true
Clojure 1.10.1
user=> (defprotocol Foo (pfoo [this]))
Foo
user=> (defn libfn [x] (pfoo x))
#'user/libfn
user=> (extend-protocol Foo String (pfoo [_] :dude))
nil
user=> (libfn "hello")
:dude
user=> (alter-var-root #'user/pfoo (fn [old] (fn [this] (prn :this) (old this))))
#object[user$eval178$fn__179$fn__180 0x18eec010 "user$eval178$fn__179$fn__180@18eec010"]
user=> (libfn "hello")
:this
:dude
我这么问是因为我正在尝试找到一种通用的方法来修复协议方法以在 sci + graal native-image 中工作。限制条件如下:
- 在直接链接下也能工作(对于原生使用很重要)
- 可与第三方库一起使用
- 避免更改目标协议的源代码(无法添加 ^:dynamic,^:redef 元数据)
我在这里有一个解决方案可以工作这里,但它依赖于在编译时,即使在直接链接下,仍然可以使用 alter-var-root 修改协议变量。这是一个安全的假设吗?