我发现我们不需要'(ns ...)
,因为ns是一个宏。 但是,为什么我们需要'在(require '[...])
?我认为Clojure的矢量是避免的一种奇特的方式,但现在我在这里看到一个。为什么我们需要'in(require'[...]])与Clojure?
我们使用(require 'clojure.string)
所以require
似乎是一个函数,但是当我们作为一个参数给出时,我们不会引用一个向量。
从没有引用该错误消息是也混乱。
我发现我们不需要'(ns ...)
,因为ns是一个宏。 但是,为什么我们需要'在(require '[...])
?我认为Clojure的矢量是避免的一种奇特的方式,但现在我在这里看到一个。为什么我们需要'in(require'[...]])与Clojure?
我们使用(require 'clojure.string)
所以require
似乎是一个函数,但是当我们作为一个参数给出时,我们不会引用一个向量。
从没有引用该错误消息是也混乱。
这是因为require
是作为一个函数实现的,而不是一个宏,因此它需要一个带引号的libspec。不加引号的libspec将被评估如下:
user=> [clojure.set :as s]
CompilerException java.lang.ClassNotFoundException: clojure.set
因此产生错误。
但是,ns
是作为一个宏实现的,并且完全控制是否或何时进一步评估它的参数,所以你不需要引用libspec。你可以看一下纳秒的宏扩展,看看会发生什么,当它展开:
user=> (use 'clojure.pprint)
nil
user=> (pprint (macroexpand '(ns foo (:require [clojure.set :as s]))))
(do
(clojure.core/in-ns 'foo)
(clojure.core/with-loading-context
(clojure.core/refer 'clojure.core)
(clojure.core/require '[clojure.set :as s]))
(if
(.equals 'foo 'clojure.core)
nil
(do
(clojure.core/dosync
(clojure.core/commute
@#'clojure.core/*loaded-libs*
clojure.core/conj
'foo))
nil)))
nil
正如你所看到的,ns
只是需要libspec,因为它是和它传递给需要之前报价为你,所以你不必。
生态位是:引用一个向量本质上是引用向量形式内的每个子形式。
user> (= '[a b c] ['a 'b 'c])
=> true
的require
形式可采取任一引用符号,参考命名空间,或者它可以采取引用符号将进一步限制的向量。
相关,几乎重复:http://stackoverflow.com/q/32783187/124319 – coredump