Clojure

REPL 編程:疑難排解

本節列出使用 REPL 時常見的問題,以及如何診斷這些問題

呼叫未定義的 Var

症狀

user=> my-nonexistent-name
Syntax error compiling at (REPL:0:0).
Unable to resolve symbol: my-nonexistent-name in this context

說明

  • 您可能在 Var 名稱中輸入錯誤,例如您應該輸入 my-non-existent-name 而不是 my-nonexistent-name

  • 您可能忘記在 REPL 中定義 my-nonexistent-name(例如使用 defdefn):如果在程式碼檔案中輸入 (def my-nonexistent-name …​) 但忘記在 REPL 中評估它,就會發生這種情況。

  • 您可能定義了 my-non-existent-name,但定義在其他命名空間中。您應該輸入 myapp.ns23/my-non-existent-name 或切換到命名空間 myapp.ns23/my-non-existent-name

使用遺失的命名空間別名

症狀

user=> ns3/foo-bar
Syntax error compiling at (REPL:0:0).
No such namespace: ns3

說明

  • 您可能在命名空間別名中輸入錯誤,例如您應該輸入 n3/foo-bar 而不是 ns3/foo-bar

  • 您可能從未在目前的命名空間中定義 ns3 別名:您可以透過評估 (require '[myapp.ns3 :as ns3]) 來修正這個問題

  • 您可能定義了 ns3 別名,但定義在與目前 REPL 所在位置不同的命名空間中。

參照未載入的命名空間

症狀

$ clj
Clojure 1.10.0
user=> clojure.set/union
Syntax error (ClassNotFoundException) compiling at (REPL:0:0).
clojure.set

說明

您正在使用 REPL 中尚未建立的命名空間。請注意,在此情況下,錯誤訊息(「ClassNotFoundException」)特別令人困惑:原因在於 Clojure 編譯器在找不到名為 clojure.set 的已載入命名空間後,會嘗試將 clojure.set 解釋為 Java 類別。解決方法是確保已載入 clojure.set 函式庫 已載入

嘗試載入不存在的命名空間

症狀

user=> (require '[a.b.c])
Execution error (FileNotFoundException) at user/eval161 (REPL:1).
Could not locate a/b/c__init.class, a/b/c.clj or a/b/c.cljc on classpath.

說明:Clojure 找不到任何名為 a.b.c 的現有命名空間,然後在類別路徑中搜尋定義它的 函式庫,最後會失敗並傳回上述例外。原因可能有所不同

  • 您可能只是在命名空間名稱中輸入錯誤

  • 您可能忘記將函式庫新增到類別路徑中,這通常是透過將其新增到專案相依性的組態中(例如在 deps.ednproject.clj 檔案中)來完成,有時(視專案管理工具而定)需要執行安裝指令(例如 lein deps)。

  • 您可能已將函式庫新增到類別路徑中,但那是您啟動 REPL 之後的事:在此情況下,您應該重新啟動 REPL。