2017-02-06 133 views

回答

10

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

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

:bar/foo是限定名称空间的关键字。该命名空间为bar,和关键字的名称是foo

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

::foo将当前命名空间与关键字相关联,使得它完全合格。假设当前的命名空间是“用户”:

*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 
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 | 
相关问题