サーチ…


構文

  • '()()
  • '(1 2 3 4 5)(1 2 3 4 5)
  • '(1 foo 2 bar 3)(1 'foo 2 'bar 3)
  • ( list 1 2 3 4 5)(1 2 3 4 5)
  • ( list* [1 2 3 4 5])(1 2 3 4 5)
  • [][]
  • [1 2 3 4 5][1 2 3 4 5]
  • ( vector 1 2 3 4 5)[1 2 3 4 5]
  • ( vec '(1 2 3 4 5))[1 2 3 4 5]
  • {} => {}
  • {:keyA 1 :keyB 2}{:keyA 1 :keyB 2}
  • {:keyA 1, :keyB 2}{:keyA 1 :keyB 2}
  • ( hash-map :keyA 1 :keyB 2){:keyA 1 :keyB 2}
  • ( sorted-map 5 "five" 1 "one"){1 "one" 5 "five"} (シーケンスとして使用すると、キーによってエントリがソートされます)
  • #{}#{}
  • #{1 2 3 4 5}#{4 3 2 5 1} (順不同)
  • ( hash-set 1 2 3 4 5)#{2 5 4 1 3} (順序なし)
  • ( sorted-set 2 5 4 3 1)#{1 2 3 4 5}

コレクション

組み込みのClojureコレクションはすべて不変で異種であり、リテラル構文を持ち、 conjcount 、およびseq関数をサポートしています。

  • conjは、アイテムが「追加」されている既存のコレクションと同等の新しいコレクションを「定数」または対数時間で返します。正確には、これはコレクションに依存します。
  • countはコレクション内のアイテムの数を一定時間で返します。
  • seqは、空のコレクションの場合はnilを返し、空でないコレクションの場合は、一連のアイテムを一定時間で返します。

リスト

リストはカッコで示されます。

()
;;=> ()

Clojureリストは単独でリンクされたリストです。新しい要素を最も効率的な場所にコレクションに「 conj 」します。リストについては、これは最初です。

(conj () :foo)
;;=> (:foo)

(conj (conj () :bar) :foo)
;;=> (:foo :bar)

他のコレクションとは異なり、空でないリストは、評価時に特別なフォーム、マクロ、関数への呼び出しとして評価されます。したがって、 (:foo) リストのリテラル表現であり、 :fooは唯一の項目としてREPL内で(:foo)評価すると、キーワードをnullary関数として呼び出すことができないため、 IllegalArgumentExceptionがスローされます

(:foo)
;; java.lang.IllegalArgumentException: Wrong number of args passed to keyword: :foo

非空のリストの評価から、Clojureのを防ぐために、次のことができquoteそれを:

'(:foo)
;;=> (:foo)

'(:foo :bar)
;;=> (:foo :bar)

残念ながら、これによって要素が評価されません。

(+ 1 1)
;;=> 2

'(1 (+ 1 1) 3)
;;=> (1 (+ 1 1) 3)

このため、通常は、引数をすべて評価し、それらの結果を使ってリストを構築するvariadic関数であるlistを使用します。

(list)
;;=> ()

(list :foo)
;;=> (:foo)

(list :foo :bar)
;;=> (:foo :bar)

(list 1 (+ 1 1) 3)
;;=> (1 2 3)

countは一定の時間内にアイテムの数を返します。

(count ())
;;=> 0

(count (conj () :foo))
;;=> 1

(count '(:foo :bar))
;;=> 2

リストを使って何かがリストであるかどうかテストできますかlist?述語:

(list? ())
;;=> true

(list? '(:foo :bar))
;;=> true

(list? nil)
;;=> false

(list? 42)
;;=> false

(list? :foo)
;;=> false

peekを使ってリストの最初の要素を得ることができます:

(peek ())
;;=> nil

(peek '(:foo))
;;=> :foo

(peek '(:foo :bar))
;;=> :foo

最初の要素を使わずにpopを使って新しいリストを得ることができます:

(pop '(:foo))
;;=> ()

(pop '(:foo :bar))
;;=> (:bar)

空のリストをpopしようとすると、 IllegalStateExceptionが発生することに注意してください。

(pop ())
;; java.lang.IllegalStateException: Can't pop empty list

最後に、すべてのリストはシーケンスなので、他のシーケンスで行うことができるリストですべてを行うことができます。実際には、空のリストを除いて、リストのseqを呼び出すと、まったく同じオブジェクトが返されます。

(seq ())
;;=> nil

(seq '(:foo))
;;=> (:foo)

(seq '(:foo :bar))
;;=> (:foo :bar)

(let [x '(:foo :bar)]
  (identical? x (seq x)))
;;=> true

シーケンス

シーケンスは非常にリストに似ています。 first要素またはrestの要素を一定時間に渡すことができる不変オブジェクトです。あなたもできるcons初めに固執するために、既存のシーケンスおよび項目から新しいシーケンスをtruct。

seq?を使って何かがシーケンスかどうかテストできますかseq?述語:

(seq? nil)
;;=> false

(seq? 42)
;;=> false

(seq? :foo)
;;=> false

ご存じのように、リストはシーケンスです:

(seq? ())
;;=> true

(seq? '(:foo :bar))
;;=> true

seqまたはrseqまたは空でないコレクションのkeysまたはvalsを呼び出すことによって得られるものもシーケンスです。

(seq? (seq ()))
;;=> false

(seq? (seq '(:foo :bar)))
;;=> true

(seq? (seq []))
;;=> false

(seq? (seq [:foo :bar]))
;;=> true

(seq? (rseq []))
;;=> false

(seq? (rseq [:foo :bar]))
;;=> true

(seq? (seq {}))
;;=> false

(seq? (seq {:foo :bar :baz :qux}))
;;=> true

(seq? (keys {}))
;;=> false

(seq? (keys {:foo :bar :baz :qux}))
;;=> true

(seq? (vals {}))
;;=> false

(seq? (vals {:foo :bar :baz :qux}))
;;=> true

(seq? (seq #{}))
;;=> false

(seq? (seq #{:foo :bar}))
;;=> true

すべてのリストはシーケンスですが、すべてのシーケンスがリストではないことに注意してください。リストはpeekpopをサポートし、一定時間内にcountcountが、通常、シーケンスはそれらの関数のどれもサポートする必要はありません。 Clojureのスタックインターフェイスもサポートしていないシーケンスでpeekまたはpopを呼び出すと、 ClassCastException

(peek (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq [:foo :bar]))
;; java.lang.ClassCastException: clojure.lang.PersistentVector$ChunkedSeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(pop (seq #{:foo :bar}))
;; java.lang.ClassCastException: clojure.lang.APersistentMap$KeySeq cannot be cast to clojure.lang.IPersistentStack

(peek (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

(pop (seq {:foo :bar :baz :qux}))
;; java.lang.ClassCastException: clojure.lang.PersistentArrayMap$Seq cannot be cast to clojure.lang.IPersistentStack

一定時間内にcountを実装しないシーケンスでcountを呼び出すと、エラーは発生しません。その代わりに、Clojureはシーケンスの終わりに達するまでシーケンス全体をトラバースし、それが通過した要素の数を返します。これは、一般的なシーケンスでは、 countは線形で一定ではなく、時間であることを意味します。あなたは何かが一定時間サポートしているかどうかをテストすることができcount使用してcounted?述語:

(counted? '(:foo :bar))
;;=> true

(counted? (seq '(:foo :bar)))
;;=> true

(counted? [:foo :bar])
;;=> true

(counted? (seq [:foo :bar]))
;;=> true

(counted? {:foo :bar :baz :qux})
;;=> true

(counted? (seq {:foo :bar :baz :qux}))
;;=> true

(counted? #{:foo :bar})
;;=> true

(counted? (seq #{:foo :bar}))
;;=> false

上で述べたように、 firstにシーケンスの最初の要素を取得することができます。 firstは引数でseqを呼び出すので、実際のシーケンスだけでなく、 "seqable"で使用できることに注意してください。

(first nil)
;;=> nil

(first '(:foo))
;;=> :foo

(first '(:foo :bar))
;;=> :foo

(first [:foo])
;;=> :foo

(first [:foo :bar])
;;=> :foo

(first {:foo :bar})
;;=> [:foo :bar]

(first #{:foo})
;;=> :foo

また、上記のように、 restを使用して、既存のシーケンスの最初の要素を除くすべてを含むシーケンスを取得することができます。 firstと同じように、引数にseqを呼び出します。しかし、結果でseqを呼び出すことはありませ !つまり、2つよりも少ないアイテムを含むシーケンスでrestを呼び出すと、 nil代わりにback ()が返されます:

(rest nil)
;;=> ()

(rest '(:foo))
;;=> ()

(rest '(:foo :bar))
;;=> (:bar)

(rest [:foo])
;;=> ()

(rest [:foo :bar])
;;=> (:bar)

(rest {:foo :bar})
;;=> ()

(rest #{:foo})
;;=> ()

シーケンス内に要素がnilときにnil返すには、 rest代わりにnextを使うことができます:

(next nil)
;;=> nil

(next '(:foo))
;;=> nil

(next [:foo])
;;=> nil

cons関数を使用すると、最初の引数をfirst引数、2番目の引数をrestとして返す新しいシーケンスを作成できます。

(cons :foo nil)
;;=> (:foo)

(cons :foo (cons :bar nil))
;;=> (:foo :bar)

Clojureは、 配列を扱うための多くの関数を持つ大規模な配列ライブラリを提供します。このライブラリの重要な点は、リストだけでなく、 "seqable"で動作することです。そういうわけで、シーケンスの概念はとても有用です。 reduceような単一の関数がすべてのコレクションに対して完全に機能することを意味します。

(reduce + '(1 2 3))
;;=> 6

(reduce + [1 2 3])
;;=> 6

(reduce + #{1 2 3})
;;=> 6

シーケンスが有用なもう一つの理由は、 firstrest特定の実装を強制するものではないため、必要なときにのみ要素が実現される遅延シーケンスが可能になるということです。

シーケンスを作成する式が与えられた場合、その式をlazy-seqマクロにラップして、シーケンスのように動作するオブジェクトを取得できますが、 seq関数ではその式を実際に評価するだけです。これは、式の結果をキャッシュし、 firstrest呼び出しをキャッシュされた結果に転送するように指示します。

有限シーケンスの場合、遅延シーケンスは通常、等価なシーケンスと同じように動作します。

(seq [:foo :bar])
;;=> (:foo :bar)

(lazy-seq [:foo :bar])
;;=> (:foo :bar)

しかし、その違いは無限のシーケンスで明らかになります。

(defn eager-fibonacci [a b]
  (cons a (eager-fibonacci b (+' a b))))

(defn lazy-fibonacci [a b]
  (lazy-seq (cons a (lazy-fibonacci b (+' a b)))))

(take 10 (eager-fibonacci 0 1))
;; java.lang.StackOverflowError:

(take 10 (lazy-fibonacci 0 1))
;;=> (0 1 1 2 3 5 8 13 21 34)

ベクトル

ベクトルは角カッコで示されます。

[]
;;=> []

[:foo]
;;=> [:foo]

[:foo :bar]
;;=> [:foo :bar]

[1 (+ 1 1) 3]
;;=> [1 2 3]

さらに、リテラル構文を使用して、 vector関数を使用してvectorを構築することもできます。

(vector)
;;=> []

(vector :foo)
;;=> [:foo]

(vector :foo :bar)
;;=> [:foo :bar]

(vector 1 (+ 1 1) 3)
;;=> [1 2 3]

ベクトルを使って何かがベクトルかどうかテストできますかvector?述語:

(vector? [])
;;=> true

(vector? [:foo :bar])
;;=> true

(vector? nil)
;;=> false

(vector? 42)
;;=> false

(vector? :foo)
;;=> false

conjは要素をベクトルの最後に追加します:

(conj [] :foo)
;;=> [:foo]

(conj (conj [] :foo) :bar)
;;=> [:foo :bar]

(conj [] :foo :bar)
;;=> [:foo :bar]

countは一定の時間内にアイテムの数を返します。

(count [])
;;=> 0

(count (conj [] :foo))
;;=> 1

(count [:foo :bar])
;;=> 2

peekを使ってベクトルの最後の要素を得ることができます:

(peek [])
;;=> nil

(peek [:foo])
;;=> :foo

(peek [:foo :bar])
;;=> :bar

popを使用して最後の要素を持たない新しいベクトルを得ることができます:

(pop [:foo])
;;=> []

(pop [:foo :bar])
;;=> [:foo]

空のベクトルをポップしようとすると、 IllegalStateExceptionが発生することに注意してください。

(pop [])
;; java.lang.IllegalStateException: Can't pop empty vector

リストとは異なり、ベクトルは索引付けされます。 getを使って、 "定数"時間のインデックスでベクトルの要素を得ることができget

(get [:foo :bar] 0)
;;=> :foo

(get [:foo :bar] 1)
;;=> :bar

(get [:foo :bar] -1)
;;=> nil

(get [:foo :bar] 2)
;;=> nil

さらに、ベクトル自体は、インデックスを取得し、そのインデックスで要素を返す関数です。

([:foo :bar] 0)
;;=> :foo

([:foo :bar] 1)
;;=> :bar

しかし、無効なインデックスを持つベクトルを呼び出すと、 nil代わりにIndexOutOfBoundsExceptionが発生します。

([:foo :bar] -1)
;; java.lang.IndexOutOfBoundsException:

([:foo :bar] 2)
;; java.lang.IndexOutOfBoundsException:

assocを使用して、特定のインデックスに異なる値を持つ新しいベクトルを取得できます。

(assoc [:foo :bar] 0 42)
;;=> [42 :bar]

(assoc [:foo :bar] 1 42)
;;=> [:foo 42]

ベクトルのcountに等しいインデックスを渡すと、Clojureはconjを使用したかのように要素を追加します。しかし、負のcountまたはより大きいcountインデックスを渡すと、 IndexOutOfBoundsExceptionが発生します。

(assoc [:foo :bar] 2 42)
;;=> [:foo :bar 42]

(assoc [:foo :bar] -1 42)
;; java.lang.IndexOutOfBoundsException:

(assoc [:foo :bar] 3 42)
;; java.lang.IndexOutOfBoundsException:

seqを使用して、ベクトル内のアイテムのシーケンスを取得できます。

(seq [])
;;=> nil

(seq [:foo])
;;=> (:foo)

(seq [:foo :bar])
;;=> (:foo :bar)

ベクトルがインデックスされているので、 rseqを使ってベクトルのアイテムの逆のシーケンスを得ることもできます:

(rseq [])
;;=> nil

(rseq [:foo])
;;=> (:foo)

(rseq [:foo :bar])
;;=> (:bar :foo)

すべてのリストはシーケンスですが、シーケンスはリストと同じ方法で表示されますが、すべてのシーケンスがリストではありません。

'(:foo :bar)
;;=> (:foo :bar)

(seq [:foo :bar])
;;=> (:foo :bar)

(list? '(:foo :bar))
;;=> true

(list? (seq [:foo :bar]))
;;=> false

(list? (rseq [:foo :bar]))
;;=> false

セット

マップと同様に、セットは連想的で順序付けられていません。キーから値へのマッピングを含むマップとは異なり、セットは基本的にキーからそれ自身にマップされます。

セットは、中括弧で区切られた8角形で表されます。

#{}
;;=> #{}

#{:foo}
;;=> #{:foo}

#{:foo :bar}
;;=> #{:bar :foo}

マップと同様に、要素がリテラルセットに現れる順序は関係ありません。

(= #{:foo :bar} #{:bar :foo})
;;=> true

セットを使用して何かがセットであるかどうかテストできますかset?述語:

(set? #{})
;;=> true

(set? #{:foo})
;;=> true

(set? #{:foo :bar})
;;=> true

(set? nil)
;;=> false

(set? 42)
;;=> false

(set? :foo)
;;=> false

containsを使用して、マップが一定の時間内に特定のアイテムを含むかどうかをテストできcontains?述語:

(contains? #{} :foo)
;;=> false

(contains? #{:foo} :foo)
;;=> true

(contains? #{:foo} :bar)
;;=> false

(contains? #{} nil)
;;=> false

(contains? #{nil} nil)
;;=> true

さらに、セット自体は要素を受け取り、その要素がセットに含まれている場合はそれを返す関数で、そうでない場合はnilを返します。

(#{} :foo)
;;=> nil

(#{:foo} :foo)
;;=> :foo

(#{:foo} :bar)
;;=> nil

(#{} nil)
;;=> nil

(#{nil} nil)
;;=> nil

conjを使用すると、既存のセットのすべての要素に加えて、1つの追加アイテムを持つセットを取得できます。

(conj #{} :foo)
;;=> #{:foo}

(conj (conj #{} :foo) :bar)
;;=> #{:bar :foo}

(conj #{:foo} :foo)
;;=> #{:foo}

disjを使って、既存のセットのすべての要素から1つのアイテムを除いたセットを取得することができます:

(disj #{} :foo)
;;=> #{}

(disj #{:foo} :foo)
;;=> #{}

(disj #{:foo} :bar)
;;=> #{:foo}

(disj #{:foo :bar} :foo)
;;=> #{:bar}

(disj #{:foo :bar} :bar)
;;=> #{:foo}

countは、要素の数を一定時間で返します。

(count #{})
;;=> 0

(count (conj #{} :foo))
;;=> 1

(count #{:foo :bar})
;;=> 2

seqを使用して、セット内のすべての要素のシーケンスを取得できます。

(seq #{})
;;=> nil

(seq #{:foo})
;;=> (:foo)

(seq #{:foo :bar})
;;=> (:bar :foo)

地図

シーケンシャルなデータ構造であるリストとは異なり、シーケンシャルでも連想的でもあるベクトルは、排他的に連想データ構造です。マップは、キーから値へのマッピングのセットで構成されます。すべてのキーはユニークなので、マップはキーから値への「定数」検索をサポートします。

マップは、中括弧で示されます。

{}
;;=> {}

{:foo :bar}
;;=> {:foo :bar}

{:foo :bar :baz :qux}
;;=> {:foo :bar, :baz :qux}

2つの要素の各ペアは、キーと値のペアです。したがって、たとえば、上記の最初のマップにはマッピングがありません。 2番目のマッピングは、キー:fooから値:barまでの1つのマッピングを持ち:bar 。 3番目のマッピングはキーからのもの、つまり:fooから値:barへのマッピングと、キー:bazから値:quxへのものの2 :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?述語:

(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

(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を使用して、マップ要素全体(キーと値を一緒に)を2要素ベクトルとして取得でき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?述語:

(map-entry? (find {:foo :bar} :foo))
;;=> true

(map-entry? [:foo :bar])
;;=> false

assocを使用すると、1つのマッピングを追加または変更して、既存のマップと同じキーと値のペアをすべて持つマップを取得できます。

(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を使用すると、既存のマップと同じキーと値のペアをすべて持つマップを取得できます。マッピングは1つ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を呼び出すことによって得られるシーケンス内のアイテムの順序は未定義です。

あなただけのキーまたは使用してマップ内だけで値のシーケンスを取得することができkeysvals 、それぞれ:

(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 "[email protected]"})

;; namespace map literal syntax
(def p #:person{:first "Darth" :last "Vader" :email "[email protected]"})


Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow