2017-02-06 19 views
5

Я столкнулся с этими ключевыми словами: :foo, ::foo, ::bar/foo, and :bar/fooВ чем разница между: foo, :: foo, :: bar/foo и: bar/foo в Clojure?

Не могли бы вы объяснить различия с примерами?

+0

Namespaced ключевые слова объясняются также в нескольких местах, которые будут найдены с помощью функции поиска. См. Https://clojuredocs.org/clojure.core/keyword и https://kotka.de/blog/2010/05/Did_you_know_III.html. – tar

ответ

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; ДР:

  • :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 |