原帖地址:http://java.ociweb.com/mark/clojure/article.html#Namespaces
作者:R. Mark Volkmann
译者:RoySong
命名空间(Namespaces)
java通过package来对类以及其中的方法来分组,而Clojure采用命名空间来对通过符号命名的东西来分组。能够
进行分组的东西包含:Vars, Refs, Atoms, Agents,
functions, macros以及命名空间本身。
符号被用来指定函数、宏和绑定的名称。而符号本身的作用域取决于它所属的命名空间。在Clojure中,总是会存在
一个默认的命名空间,最初是"user",它被保存在特殊符号*ns*中。默认命名空间可以采用两种方式来改变,
in-ns函数
仅仅改变默认命名空间,而ns宏除了改变命名空间之外还有其他功能。其中一项功能是能够使
clojure.core命名空间中
包含的符号可以在新的命名空间中生效(采用refer,接下来会讨论到
)。ns宏的其他特性将过会儿讨论。
"user"命名空间提供了对所有clojure.core命名空间中符号访问的权限。采用ns宏改变的默认命名空间同样也具备这
样的权限。
为了使用不在默认命名空间中的元素必须进行命名空间限定(namespace-qualified),在符号名前面加上命名空间
的名字和斜杠就完成了限定。举个例子, Clojure Contrib
中的str-utils库在clojure.contrib.str-utils命名空间中定
义了
str-join函数。它取出某个序列中所有元素的字符串表现,并通过指定的连接符将它们连接成一个新的字符串做为
返回值。它的命名空间限定名就是clojure.contrib.str-utils/str-join。
require函数用于加载Clojure库。它接受一个或者多个带引号的命名空间名做为参数。例子如下:
(require 'clojure.contrib.str-utils)
但这仅仅是加载了库,要使用库中的名字仍然需要采用命名空间限定。注意命名空间名和符号名采用斜杠分隔,而java
的包名和类名之间采用点来分隔。举个例子:
(clojure.contrib.str-utils/str-join "$" [1 2 3]) ; -> "1$2$3"
alias函数创建一个命名空间的引用,以免每次都要输入长长的命名空间限定。所创建引用的作用域即当前命名空间。
例子如下:
(alias 'su 'clojure.contrib.str-utils)
(su/str-join "$" [1 2 3]) ; -> "1$2$3"
refer函数可以让指定命名空间的所有符号在当前命名空间可用,而不用做命名空间限定。如果被指定的命名空间已经
在当前命名空间中定义,则会抛出一个异常。例子如下:
(refer 'clojure.contrib.str-utils)
采用了refer后之前的代码就可以写成这种形式了:
(str-join "$" [1 2 3]) ; -> "1$2$3"
require
和refer通常联合使用,所以有一个快捷函数use提供来实现它们联合的功能:
(use 'clojure.contrib.str-utils)
ns宏,之前提到过,用于改变默认命名空间。它通常用在源文件的开头。它支持以下指令::require
, :use
和:import
(用于引入java类),用于替代这些指令对应的函数形式。优先采用这些指令而不是它们对应的函数形式。在下面的例子
当中,注意采用:as来创建了一个命名空间的引用,同样也要注意采用了:only来加载Clojure库的部分:
(ns com.ociweb.demo
(:require [clojure.contrib.str-utils :as su])
(:use [clojure.contrib.math :only (gcd, sqrt)])
(:import (java.text NumberFormat) (javax.swing JFrame JLabel)))
(println (su/str-join "$" [1 2 3])) ; -> 1$2$3
(println (gcd 27 72)) ; -> 9
(println (sqrt 5)) ; -> 2.236
(println (.format (NumberFormat/getInstance) Math/PI)) ; -> 3.142
; See the screenshot that follows this code.
(doto (JFrame. "Hello")
(.add (JLabel. "Hello, World!"))
(.pack)
(.setDefaultCloseOperation JFrame/EXIT_ON_CLOSE)
(.setVisible true))
create-ns创建了一个新的命名空间,但并没将它设置为默认命名空间。
def函数在默认命名空间中采用可选的初始值
定义了一个符号;
intern函数在指定的命名空间中采用可选的初始值定义了一个符号(前提是这个命名空间中还没有相
同的符号)。注意一点,采用
intern函数时需要在符号名前加上单引号,def则不用。因为def是个特殊form,并不会对
它所有的参数求值,而intern是个函数,这代表这它会对所有的参数进行求值,例子如下:
(def foo 1)
(create-ns 'com.ociweb.demo)
(intern 'com.ociweb.demo 'foo 2)
(println (+ foo com.ociweb.demo/foo)) ; -> 3
ns-interns函数返回一个包含指定当前已加载命名空间中所有符号的map,这个map的key是符号名,value是Var对象
可能代表函数、宏或者绑定。例子如下:
(ns-interns 'clojure.contrib.math)
all-ns函数返回当前已加载命名空间的序列。当Clojure程序启动时,以下命名空间是默认加载的:
clojure.core
,
clojure.main
,
clojure.set
,
clojure.xml
,
clojure.zip和
user。在REPL中,除了上面的命名空间之外,
还会加载:clojure.contrib.repl-utils
,
clojure.contrib.seq-utils
and
clojure.contrib.str-utils。
namespace函数返回一个指定符号或者关键字对应的命名空间。
其他命名空间相关的函数在这儿就不进行讨论了,比如:ns-aliases
,
ns-imports
,
ns-map
,
ns-name
,
ns-publics
,
ns-refers
,
ns-unalias
,
ns-unmap和
remove-ns。
一些良好的输出(Some Fine Print)
Symbol对象拥有一个
String
名字和一个
String
命名空间(
调用ns),事实上它采用
字符串命名空间名代替了一个命名空间(Namespace
)对象引用,
这就允许了它可能采用的是一个实际不存在的命名空间。
Var对象拥有对一个
Symbol对象(
调用sym),一个
Namespace对象(
调用ns)和一个做为其“根值”
("root value",调用root
)的Object对象
的引用
。
Namespace对象拥有一个map的引用,这个map保存了
Symbol对象和
Var对象的联系(称作
mappings)。它们同样拥有一个包含
Symbol别名和
Namespace对象联系
(称作namespaces
)的map。看看下面的类图,展示了在Clojure实现中,java类和接口的联系的一个
小子集。在Clojure中,术语"interning"通常指添加一个Symbol
-to-Var映射到
Namespace。
分享到:
相关推荐
史上最全编程语言全套教程,共99门...函数式编程语言 壳编程语言 常见编程语言 并行编程语言 数据分析编程语言 数据库查询语言 系统编程语言 脚本编程语言 逻辑编程语言 面向对象编程语言 等所有常见的变成语言系列教程
- **Clojure**是一种运行在Java虚拟机(JVM)上的动态编程语言,它继承了Lisp家族的强大功能,同时结合了现代编程语言的优点,如面向对象编程和函数式编程。 #### 二、Clojure的特性 - **函数式编程**: Clojure强调...
Clojure是一种运行在Java虚拟机(JVM)上的动态函数式编程语言,它属于Lisp家族。Clojure的设计哲学强调了函数作为一等公民的地位,以及数据的不可变性,这些特性使得Clojure在处理并发编程和数据密集型应用时表现...
Scala和Clojure都是现代函数式编程语言,它们都运行在Java虚拟机(JVM)上,能够利用Java的生态系统和资源。Scala是一种多范式语言,结合了面向对象和函数式编程的特点,提供了强大的类型系统和模式匹配功能。...
clojure-utils, 各种小型但方便的clojure实用程序函数库 各种小型但方便的Clojure实用程序函数库特别关注:Clojure.java - 用于从Java调用Clojure的实用工具函数的Java类arrays.clj - 操作Java数组core.clj - 应该在...
1. **Clojure编程语言**:Clojure是一种基于Lisp的函数式编程语言,运行在Java虚拟机(JVM)上。它强调 immutability(不可变性)、concurrency(并发性)和functional programming(函数式编程)特性。 2. **函数...
clojure-1.5.1.jar
Clojure是一种基于Lisp的现代函数式编程语言,它运行在Java虚拟机(JVM)上,充分利用了Java平台的强大功能。SHA-3,全称为Secure Hash Algorithm 3,是美国国家标准与技术研究所(NIST)发布的一种密码散列函数标准...
虽然Java本身不是一种函数式编程语言,但是JVM强大的生态系统为运行函数式编程语言提供了坚实的基础。 本书的作者Michael Bevilacqua-Linn通过自己的经验,结合了多个编程实践者的点评,将关于Scala和Clojure中函数...
Lisp是一种古老的函数式编程语言,其主要特点是使用S-表达式(Symbolic Expression)表示数据和程序。Lisp的数据结构核心是列表,而列表是通过递归定义的,这使得在Lisp中实现递归算法变得十分自然。它的宏系统允许...
Clojure入门介绍: Clojure - Functional Programming for the JVM
Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,充分利用了Java生态系统的优势。这个压缩包很可能是Clojure 1.6.0-RC3的源代码发布,开发者可以下载、编译和测试以确保其稳定性和兼容性。 ...
Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,充分利用了Java的生态系统。这个“clojure-basics-源码.rar”压缩包很可能是包含了一些基本Clojure编程概念的示例代码或者教程。虽然没有具体...
Clojure是一种功能强大的Lisp方言,它在Java虚拟机(JVM)上运行,并且具有丰富的函数式编程特性。这个压缩包"clojure-must-watch-源码.rar"似乎包含了与Clojure相关的源代码,可能是为了帮助学习者深入理解Clojure...
该版本为稳定版,将zip文件解压,放到某个指定目录,cd进入这个目录,执行以下命令即可java -cp clojure-1.5.0.jar clojure.main。...当今最主流的运算平台JVM,把函数式编程语言引入JVM也是新方向。
Clojure是一种基于Lisp的函数式编程语言,它运行在Java虚拟机(JVM)上,充分利用了Java的生态系统。Clojure的设计目标是提供一种静态类型的、并发的、内存安全的语言,同时保持Lisp的简洁性和灵活性。在这个压缩包...
史上最全编程语言全套教程,共99门...函数式编程语言 壳编程语言 常见编程语言 并行编程语言 数据分析编程语言 数据库查询语言 系统编程语言 脚本编程语言 逻辑编程语言 面向对象编程语言 等所有常见的变成语言系列教程
《Programming Clojure 第三版》是一本深入探讨Clojure编程语言的专业书籍,旨在帮助开发者全面理解和掌握这门基于Lisp的现代函数式编程语言。Clojure是由Rich Hickey设计的,它运行在Java虚拟机(JVM)上,同时也...
clojure-cheatsheet, 用于Emacs的Clojure Cheatsheet 用于Emacs的难以置信方便的 Clojure Cheatsheet,更新为 Clojure,打包成简单,快速,可以搜索的离线形式: 状态准备使用基于 Clojure 1.7.0.安装如果你连接到 ...
- **Lisp**及其衍生语言(如Scheme和Clojure):历史悠久的函数式编程语言,支持宏定义等高级特性。 - **Scala**:结合了面向对象和函数式编程特性的多范式语言。 - **Erlang**:强调并发处理和分布式系统的函数式...