^
- это «метасимвол», который он сообщает читателю , чтобы добавить символ, начинающийся с ^
в качестве метаданных, к следующему символу (при условии, что это то, что реализует IMetas)
user=> (def x ^:IamMeta [1 2 3])
#'user/x
user=> x
[1 2 3]
user=> (meta x)
{:tag :IamMeta}
user=>
Вы можете многое узнать о том, как clojure работает под капотом, взглянув на meta
вещей, например функции:
user=> (meta foo)
{:ns #<Namespace user>,
:name foo, :file "NO_SOURCE_PATH",
:line 5, :arglists ([s])}
, это очень часто используется для типа подсказки
(defn foo [^String s] (.charAt s 1))
Обычно рекомендуется включить предупреждения об отражениях (set! *warn-on-reflection* true)
, а затем добавлять подсказки типа, пока предупреждения не исчезнут.без них Clojure будет искать тип операндов функций во время выполнения, что избавит вас от необходимости возиться с типами, хотя и за небольшую плату.
PS: Мой следующий любимый читательский персонаж - это «диспетчерский» персонаж #
, о нем стоит узнать следующее:)
PPS: это отличается от clojure 1.2.x противclojure 1.3.x в Clojure 1.2.1 метаданные не составляются, когда вы используете метасимвол:
user=> (def foo ^:foo ^:bar [1 2 3])
#'user/foo
user=> (meta foo)
{:tag :foo}
, а в 1.3 это «делает правильно», а также ключевые слова являются опциями вместо «тегов»:
user=> (def foo ^:foo ^:bar [1 2 3])
#'user/foo
user=> (meta foo)
{:foo true, :bar true}