15

ここで、優れた Clojure チュートリアルを参照しています。例の 1 つでは、次の行に沿って Clojure コードがあります。

(def vowel? (set "aeiou"))

これにより、母音の戻り値は母音に対して true になり、子音に対して false になります。

(vowel? (first "abc")) ; => true
(vowel? (first "cba")) ; => false

どうしてこれなの?変数名の後ろにある疑問符と関係があると思います。チュートリアルですぐに何も見つかりませんでした...


編集vowel?true または false を返すのではなく、要素自体または nil を返すことに気付きました。私自身の答えを見てください。

4

2 に答える 2

16

これは、マップ(Clojureで最も自然なオブジェクト)の動作と完全に類似しています。マップが関数として呼び出されると、マッピングとして機能します。

user=> (def ob {:foo "bar", :bar :baz, :qwerty 42})
#'user/ob
user=> (ob :foo)
"bar"

したがって、Clojureセットを関数として呼び出すことができ、メンバーシップテストとして機能することは理にかなっています。ちなみに、マッピングのキーとしてキーワード(コロンで始まるもの)を使用すると、それらも同様の関数として機能するので、次のことができます。

user=> (:bar ob)
:baz

そして、キーワードのセットでも同じことです。

user=> (def vowel-keywords (set [:a :e :i :o :u]))
#'user/vowel-keywords
user=> (:a vowel-keywords)
:a
user=> (:b vowel-keywords)
nil

ただし、この後者のトリックはキーワードでのみ機能し、マッピングのキーまたはセットのメンバーとして使用できるものは他にありません。

于 2009-03-26T17:33:41.333 に答える
7

あはは!結局自分で見つけました。実際にはtrueorfalseを返すのではなく、セット内の最初の出現を返すか、出現しない場合は nil を返します。

これを条件として使用できるため (nil は false として処理され、nil 以外は true として処理されます)、文字列に文字が含まれているかどうかを確認するためのちょっとしたハックとして機能します。

(vowel? (first "abc")) ; => "a"
(vowel? (first "cba")) ; => nil

(if (vowel? (first "abc"))
       (println "yay")
       (println "oops"))  ; => "yay"
于 2009-03-26T15:58:58.470 に答える