【问题标题】:Clojure weirdness with Var.intern and RT.varVar.intern 和 RT.var 的 Clojure 怪异
【发布时间】:2010-01-13 20:33:08
【问题描述】:

所以我正在尝试探索 Clojure 的内部结构,但遇到了一些我不太确定自己理解的东西:

从 REPL,我可以很好地访问 RT.var("clojure.core","re​​quire") (这应该返回与“clojure.core”命名空间中的“require”符号关联的 var) :

user=> (clojure.lang.RT/var "clojure.core" "require")
#'clojure.core/require

但是,如果我尝试以我认为相同的方式访问它(

user=> (clojure.lang.Var/intern (clojure.lang.Namespace/findOrCreate (clojure.lang.Symbol/intern nil "clojure.main")) (clojure.lang.Symbol/intern nil "require"))
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0)

我得到一个错误,要求已经引用了存在的东西。这很奇怪,因为 RT.var 与 Var.intern 相同,只是参数分别转换为 Namespace 和 Symbol。

static public Var var(String ns, String name){
    return Var.intern(Namespace.findOrCreate(Symbol.intern(null, ns)), Symbol.intern(null, name));
}

我会做更多的挖掘,但我对这个很困惑。我已经检查过: 1. nil 与 null 相同 2. 我创建了 var2,它返回发送给 Var.intern 的命名空间参数,和 var3,它返回发送给 Var.intern 的名称参数。然后我将这两个传递给 Var.intern:

user=> (clojure.lang.Var/intern
(clojure.lang.RT/var2 "clojure.main" "require")
(clojure.lang.RT/var3 "clojure.main" "require"))
java.lang.IllegalStateException: require already refers to: #'clojure.core/require in namespace: clojure.main (NO_SOURCE_FILE:0)

这可能是一个错误吗?

【问题讨论】:

    标签: java clojure


    【解决方案1】:

    这很好用:

    (clojure.lang.Var/intern
     (clojure.lang.Namespace/findOrCreate
      (clojure.lang.Symbol/create "clojure.core"))
     (clojure.lang.Symbol/create "require"))
    

    Symbol/intern 也可以:

    (clojure.lang.Var/intern
     (clojure.lang.Namespace/findOrCreate
      (clojure.lang.Symbol/intern nil "clojure.core"))
     (clojure.lang.Symbol/intern nil "require"))
    

    【讨论】:

    • 啊是的...我使用的是 clojure.main 而不是 clojure.core。谢谢!
    • 不客气!顺便说一句,我用Symbol/create 代替了Symbol/intern,但intern 也可以使用......我想我最好将它编辑进去,以免它混淆这个问题的未来访问者。 :-)
    • Symbol.intern() 和 Symbol.create() 这些天基本上做同样的事情。最初 create 会期望 interned string 作为参数,但是这种行为已经改变。 Rich 正在考虑在未来的某个时候摆脱 create()。
    • @liwp:有趣!感谢您发布此信息。 :-)
    【解决方案2】:

    REPL 只是 clojure.main,所以我们不能在 REPL 中实习 clojure.main/require,而是 clojure.core/require,我想!

    【讨论】:

      猜你喜欢
      • 2016-01-17
      • 2015-11-22
      • 1970-01-01
      • 1970-01-01
      • 2016-12-27
      • 2018-12-30
      • 2010-10-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多