与列表(它是一个顺序数据结构)和向量(它既是顺序数据又是关联数据)不同,映射完全是一个关联数据结构。映射由键到值的一组映射组成。所有键都是唯一的,因此映射支持从键到值的“恒定”时间查找。
一张映射用花括号表示:
{} ;;=> {} {:foo :bar} ;;=> {:foo :bar} {:foo :bar :baz :qux} ;;=> {:foo :bar, :baz :qux}
每对两个元素都是一个键值对。因此,例如,上面的第一个映射没有映射。第二个有一个映射,从键:foo到值:bar。第三个有两个映射,一个从键:foo的值:bar,和一个来自键:baz的值:qux。映射本质上是无序的,因此映射的显示顺序无关紧要:
(= {:foo :bar :baz :qux} {:baz :qux :foo :bar}) ;;=> true
您可以使用map?谓词测试某物是否为映射:
(map? {}) ;;=> true (map? {:foo :bar}) ;;=> true (map? {:foo :bar :baz :qux}) ;;=> true (map? nil) ;;=> false (map? 42) ;;=> false (map? :foo) ;;=> false
您可以使用谓词测试映射是否在“恒定”时间内包含给定键contains?:
(contains? {:foo :bar :baz :qux} 42) ;;=> false (contains? {:foo :bar :baz :qux} :foo) ;;=> true (contains? {:foo :bar :baz :qux} :bar) ;;=> false (contains? {:foo :bar :baz :qux} :baz) ;;=> true (contains? {:foo :bar :baz :qux} :qux) ;;=> false (contains? {:foo nil} :foo) ;;=> true (contains? {:foo nil} :bar) ;;=> false
您可以使用来获取与键关联的值get:
(get {:foo :bar :baz :qux} 42) ;;=> nil (get {:foo :bar :baz :qux} :foo) ;;=> :bar (get {:foo :bar :baz :qux} :bar) ;;=> nil (get {:foo :bar :baz :qux} :baz) ;;=> :qux (get {:foo :bar :baz :qux} :qux) ;;=> nil (get {:foo nil} :foo) ;;=> nil (get {:foo nil} :bar) ;;=> nil
此外,映射本身是接受键并返回与该键关联的值的函数:
({:foo :bar :baz :qux} 42) ;;=> nil ({:foo :bar :baz :qux} :foo) ;;=> :bar ({:foo :bar :baz :qux} :bar) ;;=> nil ({:foo :bar :baz :qux} :baz) ;;=> :qux ({:foo :bar :baz :qux} :qux) ;;=> nil ({:foo nil} :foo) ;;=> nil ({:foo nil} :bar) ;;=> nil
您可以使用find以下元素将整个映射条目(键和值一起)作为两个元素的向量获得:
(find {:foo :bar :baz :qux} 42) ;;=> nil (find {:foo :bar :baz :qux} :foo) ;;=> [:foo :bar] (find {:foo :bar :baz :qux} :bar) ;;=> nil (find {:foo :bar :baz :qux} :baz) ;;=> [:baz :qux] (find {:foo :bar :baz :qux} :qux) ;;=> nil (find {:foo nil} :foo) ;;=> [:foo nil] (find {:foo nil} :bar) ;;=> nil
您可以分别使用key或从映射条目中提取键或值val:
(key (find {:foo :bar} :foo)) ;;=> :foo (val (find {:foo :bar} :foo)) ;;=> :bar
请注意,尽管所有Clojure映射条目都是矢量,但并非所有矢量都是映射条目。如果您尝试拨打电话key或拨打val任何非映射条目的电话,都会收到ClassCastException:
(key [:foo :bar]) ;; java.lang.ClassCastException: (val [:foo :bar]) ;; java.lang.ClassCastException:
您可以使用map-entry?谓词测试某项是否是映射条目:
(map-entry? (find {:foo :bar} :foo)) ;;=> true (map-entry? [:foo :bar]) ;;=> false
您可以assoc用来获取具有与现有映射相同的键值对的映射,并添加或更改一个映射:
(assoc {} :foo :bar) ;;=> {:foo :bar} (assoc (assoc {} :foo :bar) :baz :qux) ;;=> {:foo :bar, :baz :qux} (assoc {:baz :qux} :foo :bar) ;;=> {:baz :qux, :foo :bar} (assoc {:foo :bar :baz :qux} :foo 42) ;;=> {:foo 42, :baz :qux} (assoc {:foo :bar :baz :qux} :baz 42) ;;=> {:foo :bar, :baz 42}
您可以dissoc用来获取具有与现有映射相同的键/值对的映射,并可能删除了一个映射:
(dissoc {:foo :bar :baz :qux} 42) ;;=> {:foo :bar :baz :qux} (dissoc {:foo :bar :baz :qux} :foo) ;;=> {:baz :qux} (dissoc {:foo :bar :baz :qux} :bar) ;;=> {:foo :bar :baz :qux} (dissoc {:foo :bar :baz :qux} :baz) ;;=> {:foo :bar} (dissoc {:foo :bar :baz :qux} :qux) ;;=> {:foo :bar :baz :qux} (dissoc {:foo nil} :foo) ;;=> {}
count 以固定时间返回映射数:
(count {}) ;;=> 0 (count (assoc {} :foo :bar)) ;;=> 1 (count {:foo :bar :baz :qux}) ;;=> 2
您可以使用以下命令获取映射中所有条目的序列seq:
(seq {}) ;;=> nil (seq {:foo :bar}) ;;=> ([:foo :bar]) (seq {:foo :bar :baz :qux}) ;;=> ([:foo :bar] [:baz :qux])
同样,映射是无序的,因此您通过调用seq映射获得的序列中项目的顺序是不确定的。
您可以分别使用keys或来获取仅键的序列或映射中的值vals:
(keys {}) ;;=> nil (keys {:foo :bar}) ;;=> (:foo) (keys {:foo :bar :baz :qux}) ;;=> (:foo :baz) (vals {}) ;;=> nil (vals {:foo :bar}) ;;=> (:bar) (vals {:foo :bar :baz :qux}) ;;=> (:bar :qux)
Clojure 1.9添加了文字语法,以更简洁地表示键共享相同名称空间的映射。请注意,两种情况下的映射都是相同的(映射不“知道”默认名称空间),这只是语法上的方便。
;; typical map syntax (def p {:person/first"Darth" :person/last "Vader" :person/email "darth@death.star"}) ;; namespace map literal syntax (def p #:person{:first "Darth" :last "Vader" :email "darth@death.star"})
引导任务boot cljs repl提供了一种连接到ClojureScript repl的方法,ClojureScript repl与正在运行的浏览器实例交互。 如果正确地添加到build.boot依赖项中,可以从Clojure repl中调用函数,以便启动ClojureScript REPL。 我正在使用Emacs通过苹果酒软件包连接clojure REPL,该软件包具有以下功能: 我试图弄清楚
Clojure是一种LISP风格的语言,运行在JVM上。Clojure的一大特色就是其并发机制,它支持不可变的数据结构(Clojure是来自于可持久化的数据结构)。Clojure还有一个特色是软件事务存储(Software Transactional Memory,STM),其支持用事务代替锁和互斥器来更新共享内存。STM还是一个有争议的技术,还需要更好的证明自己,一个简单的办法就是访问一个JVM上的实现。
从Clojoure调用Java非常简单明了,但反过来已被证明是不可预测的。 它们似乎有两种方式: 1)以下类别 2) 将clojure编译成uberjar,然后将其导入java代码。 我选择了第二个选项,因为它更直接。 这是clojure代码 这是Java代码。 当我做出“service.returned(4);”时,系统永远不会返回。我不太明白为什么对我来说,它会像函数没有从Clojure返回一
我正在通过编程Clojure书学习Clojure,但很早就想从书中找到一个例子。 我从书中下载了代码示例;目录结构为 其中有一堆.clj文件,包括一个名为induction.clj的文件。 我试图运行的代码以 ...但我不能让它发挥作用。 我试着添加一个checkouts目录,并将其中的examples目录符号化。我试过用manifest.txt创建一个.jar文件,给出了1.0.0版本....
本文向大家介绍clojure is,包括了clojure is的使用技巧和注意事项,需要的朋友参考一下 示例 该is宏是核心clojure.test库。它返回其主体表达式的值,如果该表达式返回假值,则输出错误消息。
我用lein uberjar创建了一个uberjar,我可以通过以下方式在我的机器上运行它(安装了java 1.8): 在我想要部署它的服务器上,出现了一个错误。然而,这里只安装了java 1.5版。以下是错误消息和完整的版本说明: