有什么区别:foo,:: foo,:: bar / foo,以及:Clojure中的bar / foo?

时间:2017-02-06 14:54:07

标签: clojure functional-programming lisp clojurescript

我遇到了这些关键字::foo, ::foo, ::bar/foo, and :bar/foo

你能用例子来解释差异吗?

2 个答案:

答案 0 :(得分:10)

:foo是非完全限定的关键字。它没有与之关联的命名空间。

(name :foo)            ; => "foo"
(namespace :foo)       ; => nil

:bar/foo是一个名称空间限定的关键字。名称空间为bar,关键字的名称为foo

(name :bar/foo)        ; => "foo"
(namespace :bar/foo)   ; => "bar"

::foo会将当前命名空间与关键字相关联,使其完全合格。假设当前命名空间是“user”:

*ns*                   ; => #namespace[user]
(name ::foo)           ; => "foo"
(namespace ::foo)      ; => "user"
::foo                  ; => :user/foo

::bar/foo将尝试扩展任何别名以使其完全合格:

(create-ns 'my.namespace)       ; => #namespace[my.namespace]
(alias 'bar 'my.namespace)      ; => nil
(name ::bar/foo)                ; => "foo"
(namespace ::bar/foo)           ; => "my.namespace"
::bar/foo                       ; => :my.namespace/foo

答案 1 :(得分:3)

This article解释得很清楚。

TL; DR:

  • :foo是没有命名空间的关键字,即非限定关键字。
  • :foo/bar是具有显式名称空间foo的限定关键字。
  • ::foo是自动限定的关键字。如果此关键字出现在命名空间bar中,则会将其评估为:bar/foo
  • 如果您需要名称空间::bar/foo:baz/foo的名称空间与bar :as baz相同。

在代码中:

boot.user=> (ns foo)
nil
foo=> (ns bar (:require [foo :as f]))
nil
bar=> (def examples [:foo ::foo ::f/foo :bar/foo])
#'bar/examples
bar=> examples
[:foo :bar/foo :foo/foo :bar/foo]
bar=> (use 'clojure.pprint)
nil
bar=> (print-table (map (fn [example] 
                          {:key example :namespace (namespace example)
                           :name (name example)}) 
                     examples))

|     :key | :namespace | :name |
|----------+------------+-------|
|     :foo |            |   foo |
| :bar/foo |        bar |   foo |
| :foo/foo |        foo |   foo |
| :bar/foo |        bar |   foo |