15

我在这里查看优秀的 Clojure 教程。在其中一个示例中,它的 Clojure 代码如下:

(def vowel? (set "aeiou"))

这使得元音对元音返回真,对辅音返回假:

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

为什么是这样?我假设它与变量名后面的问号有关。在教程中找不到任何东西...


编辑我刚刚意识到vowel?不返回真或假,而是元素本身或零。看我自己的答案。

4

2 回答 2

16

这与地图(Clojure 中最自然的对象)的工作方式非常相似。当 map 作为函数调用时,它作为映射工作:

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

啊哈!我最终自己发现了。它实际上并不返回trueor false,而是返回集合中的第一次出现,如果没有出现,则返回 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 回答