阅读Clojure API的导入部分,我发现ns宏中的:import优先于import使用。然而,当我使用swank/slime/emacs编码时,我无法将(ns...)s表达式c-x c-e到repl中获取依赖项,但是使用(import ...)可以。为什么要优先选择:import而不是import?是否有一种快速的方法可以从我的.clj文件中的(ns...)s表达式中导入依赖项到repl中?(相同的问题也适用于:use和:refer..感谢)
ns
声明,并在更改时使用C-c C-k(包括ns
导入)。(ns ...)形式更受青睐,因为它可以使你的代码更易读。所有命名空间声明将被收集在文件的顶部。在像Java这样的语言中,编译器会执行此操作。而且,包含宏ns消除了引用符号的需要。use、import、refer等也是如此。
我认为C-x C-e
快捷键将发送代码片段到连接的Swank服务器,并对其进行评估。例如,如下表达式:
(ns my.test
(:require [clojure.contrib.logging :as log])
(:import [java.io File]))
C-c M-p
,然后会提示您切换到该文件的命名空间的名称(除非您已经在该命名空间中)。按Enter键选择。 C-c C-z
应该切换到repl。现在,您将看到 my.test =>
而不是 user =>
提示,表示您在该命名空间中。
我设置的工作流是在保存时编译整个文件,使用:
(defun ed/clojure-compile-on-save (&optional args)
"Compile with slime on save"
(interactive)
(if (and (eq major-mode 'clojure-mode)
(slime-connected-p))
(slime-compile-and-load-file)))
(add-hook 'after-save-hook 'ed/clojure-compile-on-save)
这样一来,每当我保存文件时,它都会被编译并由Swank服务器加载,我可以在命名空间中使用REPL进行实验。
我不确定为什么 c-x c-e 无法工作,但只要命名空间已经存在,ns 表达式上的 C-c C-c 就可以正确工作。
:在ns声明中的import是首选,因为它将与命名空间相关的所有内容放在一个地方,通常在文件顶部。这是良好的编码实践。
我认为解析ns声明C-x C-e无法工作是SLIME工作方式的一部分。当您评估一个sexp时,SLIME会在当前命名空间中执行它。因此,评估(import 'java.io.File)
将导入File到目前包含在ns
中的任何命名空间。
评估(ns my.namespace (:import java.io.File)声明确实修改了声明中指定的命名空间,但它不会改变ns
的值。除非您使用(in-ns'my.namespace)更改到该命名空间,否则您将看不到导入。