`
xiuzhuchenqing
  • 浏览: 16188 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Clojure中的命名空间

 
阅读更多

一个缺乏语义元素组织管理框架的编程语言会显得杂乱无章,并且会导致各种莫名的问题,当然而今这样的语言似乎很难生存。

Clojure也有自己的命名空间,不同于Java等其他语言的是,clojure在逻辑上的组织并非由目录的自然组织方式决定(大多数时候人们还是习惯这么做的,比较直观)。Java将方法组织在一个类中,而类又被组织在包中。Clojure则将包括VarsRefsAtomsAgentsfunctionsmocros、甚至namespace自己都组织到以symbols命名的namespace中。

Symbols被用于给函数、宏和绑定变量分配名称。Symbols被划分到namespace中。当前总有一个默认的namespace,初步设置在”user”中,并且这个值是保存在全局变量*ns*中的。有两种方式可以改变默认的namespacein-ns仅仅是改变它,而ns宏除了改变它还会将 clojure.core namespace中的所有symbols在新的namespace中设为可用状态(通过refer)。有关ns的宏的更多特性随后进行阐述。

user名称空间,可以访问clojure.core名称空间中所有的符号。同样通过使用ns宏所声明的任何名称空间也能够访问clojure.core名称空间中所有的符号。

 

要访问元素如果不在默认的名称空间中,那么这些元素必须加上namespace限定符。只需在namespace名称后加上一个斜杠再加上name就可以。例如clojure.string库中定义了join函数。它可以将一个序列中的所有项的字符串表示形式加上一个给定的分隔符连接成一个字符串。该函数的namespace限定符(namespace-qualified)clojure.string/join。

 

函数require用于载入Clojure库。它接受一到多个namespace的引用名称。例如:

 

(require 'clojure.string)

 

 

 (require namespace-qualified)只会载入这个类库。这里面的名字还必须是一个全限定的包名, 包名之间用.分割。注意,clojure里面名字空间和方法名之间的分隔符是/而不是java里面使用的. 。例如:

 

(clojure.string/join "$" [1 2 3]) ; -> "1$2$3"

 

 

alias 函数给一个名字空间指定一个别名以减少我们打字工作。当然这个别名的定义只在当前的名字空间里面有效。例如:

 

(alias 'su 'clojure.string)
(su/join "$" [1 2 3]) ; -> "1$2$3"

 

 

refer 函数使得指定的名字空间里面的所有symbols在当前名字空间里面可以访问(不用使用全限定名字)如果当前名字空间有那个名字空间一样的名字,会抛出一个异常。通过指定名字空间的可以解决这一问题。  例如:

 

(refer 'clojure.string)

 

  这时之前得代码可以写成如下形式:

 

(join "$" [1 2 3]) ; -> "1$2$3"
 

 

require和refer经常被联合使用,因此有了其便捷版本use,如下所示:

(use 'clojure.string)

 

 

之前提到过的ns宏可以改变默认的namespace。比较典型的用法是至于一个clojure源文件的头部。它支持:require\:use\:import(用于引入java),用于替代他们所代指的函数形式。注意下面的示例中,:as是用于创建一个namespace的别名。:only则用于仅载入一个Clojure库的某部分。

 

(ns com.ociweb.demo
  (:require [clojure.string :as su])
  ; assumes this dependency: [org.clojure/math.numeric-tower "0.0.1"]
  (:use [clojure.math.numeric-tower :only (gcd, sqrt)])
  (:import (java.text NumberFormat) (javax.swing JFrame JLabel)))

(println (su/join "$" [1 2 3])) ; -> 1$2$3
(println (gcd 27 72)) ; -> 9
(println (sqrt 5)) ; -> 2.23606797749979
(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创建一个新的namespace,但并没有设置为当前默认的。def函数则在默认的namespace中创建一个带有一个可选初值的symbolintern函数则在给定的namespace中定义一个symbol(如果该symbol不存在的话),也可以为其设置一个初值。注意intern中的symbol的名称需要一个引号,def的是不需要的。这是因为def是一个不需要求值它的所有参数的特殊形式,而intern是一个函数,意味着它需要对它所有的参数求值。

 

(def foo 1)
(create-ns 'com.ociweb.demo)
(intern 'com.ociweb.demo 'foo 2)
(println (+ foo com.ociweb.demo/foo)) ; -> 3

 

 

  ns-interns函数返回一个包含所有在给定并且已经载入namespace中定义的symbolsmapmap的键是所有的Symbol对象的名称,而值则是一个个代表函数、宏或者绑定变量的Var对象。

 

ns-interns 'clojure.math.numeric-tower)
 

 

 

all-ns函数返回当前载入的namespace序列。当一个clojure程序在运行时,默认载入了以下namespaceclojure.coreclojure.mainclojure.set,clojure.xmlclojure.zip and user

REPL环境中默认载入的namespace还有clojure.repl clojure.java.javadoc。namespace函数返回给定symbol或者关键词的namespace。这里没有讨论到的和namespace有关的函数包括ns-aliases, ns-imports, ns-map, ns-name, ns-publics, ns-refers, ns-unalias, ns-unmap and remove-ns

 

 

 

分享到:
评论

相关推荐

    txload:Clojure 命名空间的透明事务加载

    仅在命名空间加载在 Clojure 中进行事务处理时才需要此库。 安装 将以下内容添加到 project.clj 中的依赖项向量: [txload " 0.1.1 " ] 最新: 用法 在执行需要从不同线程动态加载 Clojure 命名空间的代码之前,...

    clj-osgi-namespaces:Clojure OSGI命名空间

    Clojure库设计用于在OSGI容器中运行时导入和导出clojure名称空间。 汇编 lein javac lein uberjar 将生成的* -standalone.jar放入OSGI自动加载(bundles /)文件夹中 用法 支持以下非标准OSGI Manfiest标头 ...

    ns-reload:正确重新加载您的 clojure 命名空间

    ns-重新加载用于正确重新加载命名空间的 Clojure 库。安装将[[com.palletops/ns-reload "0.1.0"]]到您的:plugins中的:user配置profiles.clj 。用法( require '[com.palletops.ns-reload :refer :as deps]) 重新加载...

    Clojure Handbook(2012.11.1)

    在学习Clojure的过程中,Handbook介绍了语言的基础知识,如REPL(Read-Eval-Print Loop)交互式环境、变量定义、基本类型、类型判断、执行多条语句的do表达式、条件语句、循环语句、正则表达式、命名空间、结构体...

    clojure programming

    在本书的剩余部分,作者将带领读者深入了解Clojure的命名空间、符号评估、特殊形式、字面量、注释、空白和逗号、集合字面量以及读者糖等细节,并通过实际案例演示如何使用Clojure解决实际编程问题。 总之,本书对于...

    racket-clojure:#lang clojure

    #lang clojure 该项目是Racket中Clojure兼容语言的存根。 它的主要目的是让我练习编写宏和使用Racket的语言扩展工具。... 使用模块/命名空间模拟Clojure命名空间模拟Clojure宏模拟Clojure协议clojure/*下的更多兼容性

    在eclipse上面搭建Clojure开发运行环境

    在源代码文件中,你可以创建一个名为`lein-test`的命名空间(例如`(ns myproject.core-test)`),然后编写测试用例。通过右键点击源文件并选择"Run As" -> "Clojure Test",Eclipse会运行所有相关的测试。 此外,...

    namespacefy:用于命名空间关键字的Clojure(Script)帮助器库

    你可以通过`ns`宏来定义命名空间,并使用`require`、`use`或`refer`来引入其他命名空间中的符号。 `namespacefy`库提供的功能可能包括: 1. **关键词到命名空间的转换**:这个库可能包含一个函数,将像`:...

    Clojure Handbook (by jamesqiu).pdf

    2.10 命名空间:在Clojure中,命名空间是代码组织的基本单位,它用于避免名称冲突。 2.11 结构体:Clojure提供结构体(defstruct)的定义,用于创建具有固定字段的数据类型。 2.12 类:虽然Clojure以函数式编程为...

    vocabulary:在 clojure 命名空间关键字和 RDF 样式 URI 之间映射的实用程序

    支持 SPARQL 查询sparql-prefixes-for prepend-prefix-declarations 公共链接数据命名空间用_ont-app.vocabulary.core 导入使用 ont-app.vocabulary.wikidata 导入导入了ont-app.vocabulary.linguistics 语言标记...

    states:Clojure 中状态计算的基于属性的生成测试

    让我们从需要必要的命名空间开始。 ( require '[clojure.test.check :refer [quick-check]] '[clojure.test.check.generators :as gen] '[states.core :refer [run-commands]]) 我们要在测试集上调用的命令必须使用...

    clojure 速查表

    - `dir`:列出命名空间中的符号。 - `source`:显示源代码。 - `pst`:查看宏的扩展。 - `javadoc`:获取 Java 文档。 #### 三、原始类型 - **Numbers**:数字类型。 - **Literals**:字面量表示。 - Long:`...

    typed-logging:clojure.tools.logging库的core.typed批注

    类型记录 一个Clojure库,为clojure.tools.logging库提供core.typed批注。 用法 只需将注释添加到执行日志记录的模块中... 但是,clojure.tools.logging命名空间提供了其他扩展该接口的宏,并且众所周知,这些宏不会

    helm-clojure:基于 helm 和 cider 的 Emacs 包旨在探索 Clojure 的项目环境

    掌舵人 基于和Emacs 包旨在探索 Clojure 的项目环境。...helm-clojure 足够聪明,可以插入关于当前命名空间的引用。 如果 var 或 var 的命名空间一般已经被引用到命名空间,则将在没有命名空间的情况下插入; 如

    config:使用EDN配置文件在Clojure中管理环境变量的库

    2. 导入库:在你的Clojure源代码中,导入`taoensso.config`命名空间,`(:require [taoensso.config :as config])`。 3. 加载配置:使用`config/load-config!`函数加载配置文件。你可以传递配置文件的路径,或者不传...

    defexception:一个简单的Clojure库,用于在Clojure中动态定义Java Exception类

    例外 一个简单的Clojure库,该库允许在Clojure中动态定义Java Exception类。 动机 有时,您只需要可以直接捕获的快速Exception类。 defexception使用Java... 这也将import类到当前的命名空间,并创建一个辅助功能fo

    clojure-style-guide:Clojure编程语言的社区编码风格指南

    - 命名空间(namespace)采用点分隔的命名方式,表示模块或包层次,如`my.app.core`。 2. **代码结构**: - 使用`(defn)`定义函数,参数列表放在括号内,函数体使用大括号包裹。 - 长函数应拆分为多个短函数,每...

    clojure-init:发情的slo clojure

    4. **命名空间(Namespaces)**:Clojure中的命名空间是组织代码的基本单位,类似于其他语言的模块或包。通过`ns`宏定义命名空间,并可以导入其他命名空间的函数和变量。 5. **核心库导入**:Clojure提供了丰富的...

    pdfboxing:Clojure中PDFBox的不错包装

    然后,导入必要的命名空间,并根据需求调用相应的函数。由于PDFboxing是基于PDFBox,因此其底层能力强大,能够处理复杂的PDF操作。 在`pdfboxing-master`这个压缩包中,你可能会找到项目的源代码、示例、测试以及...

Global site tag (gtag.js) - Google Analytics