Nil? переменная разрешения возвращает ноль после определения - PullRequest
0 голосов
/ 07 марта 2020

Я новичок в Clojure, так что это может быть очевидно.

(println (nil? (resolve 'x)))
(def x 1)
(println (nil? (resolve 'x)))

Это печатает

true
true

Почему второй println не выводит false?

В соответствии с примерами ClojureDocs , разве это не должно иметь место?

РЕДАКТИРОВАТЬ:

Я не , запустив это через REPL.

Вот как я туда попал:

Создайте проект через lein new testing.

После внесения изменений в ядро. clj, это выглядит так:

(ns testing.core
  (:gen-class))

(defn -main
  [& args]

  (println (nil? (resolve 'x)))
  (def x 1)
  (println (nil? (resolve 'x)))
)

При запуске через lein run вывод:

true
true

Ответы [ 4 ]

0 голосов
/ 08 марта 2020

Попробуйте вместо этого запустить следующую программу и внимательно прочитайте вывод. Обратите внимание, что строка do c для функции 'resol' говорит о том, что она разрешает символ в пространстве имен, который является текущим значением * ns *, и это "dynamici c var", который в соответствии с выводом программы, показанной ниже, по умолчанию равен пространству имен 'user', отличается от пространства имен, в котором определена функция; это пространство имен, где 'x' равно 'def'd.

(ns testing.core
  (:gen-class))

(defn -main
  [& args]

  (println)
  (println "before (def x 1)")
  (println "*ns*=" *ns*)
  (println "(resolve 'x)=" (resolve 'x))
  (println "(resolve 'user/x)=" (resolve 'user/x))
  (binding [*ns* 'testing.core]
    (println "*ns*=" *ns*)
    (println "(resolve 'x)=" (resolve 'x))
    (println "(resolve 'user/x)=" (resolve 'user/x)))

  (def x 1)
  (println)
  (println "after (def x 1)")
  (println "*ns*=" *ns*)
  (println "(resolve 'x)=" (resolve 'x))
  (println "(resolve 'user/x)=" (resolve 'user/x))
  (binding [*ns* 'testing.core]
    (println "*ns*=" *ns*)
    (println "(resolve 'x)=" (resolve 'x))
    (println "(resolve 'user/x)=" (resolve 'user/x))))

Вывод в моей системе:

before (def x 1)
*ns*= #object[clojure.lang.Namespace 0x524f3b3a user]
(resolve 'x)= nil
(resolve 'user/x)= nil
*ns*= testing.core
(resolve 'x)= #'testing.core/x
(resolve 'user/x)= nil

after (def x 1)
*ns*= #object[clojure.lang.Namespace 0x524f3b3a user]
(resolve 'x)= nil
(resolve 'user/x)= nil
*ns*= testing.core
(resolve 'x)= #'testing.core/x
(resolve 'user/x)= nil
0 голосов
/ 07 марта 2020

(resolve 'x) попытаться получить переменную с именем (привязанным) к символу x. Если этот Var не существует, он должен вернуть ноль. Так что ваши предположения верны. Если вы кодируете с помощью живого REPL, помните, что код, который вы оцениваете, остается в памяти, пока вы не замените его новой версией или не отмените его вручную.


Вот визуальный сеанс REPL с моей стороны, показывающий правильное поведение:

Screen recording of a REPL session described in this post

0 голосов
/ 07 марта 2020

В вашей среде есть что-то странное:

~/expr/demo > lein repl
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (resolve 'x)
nil
demo.core=> (def x 1)
#'demo.core/x
demo.core=> (resolve 'x)
#'demo.core/x
0 голосов
/ 07 марта 2020

Когда я оцениваю эти выражения в Clojure REPL, я получаю значение true для первого и false для второго. Как вы начинаете Clojure REPL? Какую версию Clojure вы используете? Можете ли вы воспроизвести это последовательно?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...