Умови читача

Ця особливість мови дає можливість діалектам Clojure використовувати код на різних платформах та мати частини коду, специфічні до кожної з цих платформ.

Умови читача можна використовувати лише у файлах .cljc. Тому усі файли, в яких ви хочете використати умови читача, вам треба перейменувати у .cljc.

Стандартна умова (#?)

Існує два типи умов читача: стандартна та розгортуюча. Стандартна умова читача поводиться приблизно так само, як конструкція cond, але синтаксис виглядає по–іншому:

(defn parse-int
  [v]
  #?(:clj  (Integer/parseInt s)
     :cljs (js/parseInt s)))

Як ви можете бачити макрос #? дуже схожий на cond, але відрізняється тим, що умови представлені ключовими словами, що ідентифікують платформу. :cljs означає, що цей код буде використаний лише для ClojureScript, а :clj — для Clojure. Перевагою такого підходу є те, що умови читача обчислюються на етапі компіляції, тому у скомпільованому коді буде лише код для конкретної платформи.

Розгортуюча умова (#?@)

Розгортуюча умова читача працює так само, як і стандартна, але також дозволяє розгортати списки у окремі форми. Синтаксис макросу #?@ виглядає наступним чином:

(defn make-list
  []
  (list #?@(:clj  [5 6 7 8]
            :cljs [1 2 3 4])))

;; On ClojureScript
(make-list)
;; => (1 2 3 4)

Після прочитання коду компілятор ClojureScript залишить лише код для ClojureScript:

(defn make-list
  []
  (list 1 2 3 4))

Розгортуюча умова читача не може бути використана для розгорнення декількох форм на вищому рівні простору імен:

#?@(:cljs [(defn func-a [] :a)
           (defn func-b [] :b)])
;; => #error "Reader conditional splicing not allowed at the top level."

Для цього можна використати стандартну умову для кожної форми окремо, або загорнути їх у блок do:

#?(:cljs (defn func-a [] :a))
#?(:cljs (defn func-b [] :b))

;; Or

#?(:cljs
   (do
     (defn func-a [] :a)
     (defn func-b [] :b)))

Додаткові матеріали

results matching ""

    No results matching ""