为什么 Clojure 在创建新的命名空间后不提供标准库?
Why Doesn't Clojure provide standard library after creating new namespace?
我在创建新命名空间后遇到了这个问题。
代码如下:
(create-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]
(in-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]
(reduce + [1 2 3])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: reduce in this context, compiling:(/private/var/folders/pg/bynypsm12nx1s4gzm56mwtcr0000gn/T/form-init1425759900088902804.clj:1:1)
如您所见,reduce
函数未在 my-new-ns
命名空间中定义。
我应该能够创建新的命名空间,所以 这个问题的最佳解决方案是什么?
P.S:此外,我正在尝试为我的用户创建这些命名空间,以便他们能够在其命名空间中做任何他们想做的事情(这个想法就像一个容器)并在命名空间之间创建隔离.
您的新命名空间需要使用 "standard" 命名空间才能解析其中的名称。文档表明这将是 java.lang
、clojure.lang.Compiler
和 clojure.core
.
我建议使用 ns
宏,而不是手动创建命名空间然后切换到它。根据文档:
Sets *ns* to the namespace named by name (unevaluated), creating it if needed.
它还会 load all public vars 从 clojure.core
到新创建的命名空间。
所以,基本上是这样
> (create-ns 'my-new-ns)
> (in-ns 'my-new-ns)
> (clojure.core/refer 'clojure.core)
等于这个
> (ns my-new-ns)
更新:
回答您的问题:来自标准库的符号在新创建的命名空间中不是 refer
红色,这就是为什么您不能在没有限定符的情况下访问它们:
> (create-ns 'x)
> (in-ns 'x)
> reduce ;; throws "Unable to resolve symbol"
> clojure.core/reduce ;; works fine
您需要通过调用 (clojure.core/refer 'clojure.core)
.
手动引用这些符号
我想你应该使用
(ns my-new-ns)
相反。 create-ns
是 low-level 设施。
clojure.core 函数在需要引用以使它们可用于非限定用途方面并不特殊。 ns
宏做了几件事:
- 创建命名空间 -
create-ns
- 将当前命名空间更改为该命名空间 -
in-ns
- 自动将所有 clojure.core 变量引用到新命名空间中 -
refer-clojure
您始终可以使用 qualified 形式的核心函数(不合格只是少打字),所以当您遇到这种情况时,这个简单的调用会让您再次正确:
(clojure.core/refer-clojure)
我在创建新命名空间后遇到了这个问题。
代码如下:
(create-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]
(in-ns 'my-new-ns)
=> #object[clojure.lang.Namespace 0x7c7c8359 "my-new-ns"]
(reduce + [1 2 3])
CompilerException java.lang.RuntimeException: Unable to resolve symbol: reduce in this context, compiling:(/private/var/folders/pg/bynypsm12nx1s4gzm56mwtcr0000gn/T/form-init1425759900088902804.clj:1:1)
如您所见,reduce
函数未在 my-new-ns
命名空间中定义。
我应该能够创建新的命名空间,所以 这个问题的最佳解决方案是什么?
P.S:此外,我正在尝试为我的用户创建这些命名空间,以便他们能够在其命名空间中做任何他们想做的事情(这个想法就像一个容器)并在命名空间之间创建隔离.
您的新命名空间需要使用 "standard" 命名空间才能解析其中的名称。文档表明这将是 java.lang
、clojure.lang.Compiler
和 clojure.core
.
我建议使用 ns
宏,而不是手动创建命名空间然后切换到它。根据文档:
Sets *ns* to the namespace named by name (unevaluated), creating it if needed.
它还会 load all public vars 从 clojure.core
到新创建的命名空间。
所以,基本上是这样
> (create-ns 'my-new-ns)
> (in-ns 'my-new-ns)
> (clojure.core/refer 'clojure.core)
等于这个
> (ns my-new-ns)
更新:
回答您的问题:来自标准库的符号在新创建的命名空间中不是 refer
红色,这就是为什么您不能在没有限定符的情况下访问它们:
> (create-ns 'x)
> (in-ns 'x)
> reduce ;; throws "Unable to resolve symbol"
> clojure.core/reduce ;; works fine
您需要通过调用 (clojure.core/refer 'clojure.core)
.
我想你应该使用
(ns my-new-ns)
相反。 create-ns
是 low-level 设施。
clojure.core 函数在需要引用以使它们可用于非限定用途方面并不特殊。 ns
宏做了几件事:
- 创建命名空间 -
create-ns
- 将当前命名空间更改为该命名空间 -
in-ns
- 自动将所有 clojure.core 变量引用到新命名空间中 -
refer-clojure
您始终可以使用 qualified 形式的核心函数(不合格只是少打字),所以当您遇到这种情况时,这个简单的调用会让您再次正确:
(clojure.core/refer-clojure)