почему "(def vowel? (set" aeiou "))" работает? - PullRequest
15 голосов
/ 26 марта 2009

Я смотрю на превосходный учебник Clojure здесь . В одном из примеров он имеет код Clojure в следующих строках:

(def vowel? (set "aeiou"))

Это делает возврат гласного истинным для гласных и ложным для согласных:

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

Почему это? Я предполагаю, что это как-то связано с вопросительным знаком за именем переменной. Не могу найти что-нибудь сразу в учебнике ...


Редактировать Я только что понял, vowel? не возвращает истину или ложь, а сам элемент или ноль. Смотри мой собственный ответ.

Ответы [ 2 ]

16 голосов
/ 26 марта 2009

Это совершенно аналогично тому, как работают карты (самые естественные объекты в 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

Но, опять же, этот последний трюк работает только с ключевыми словами, а не с чем-либо еще, что вы могли бы использовать в качестве ключей в сопоставлении или членов в наборе.

7 голосов
/ 26 марта 2009

Aha! Я в конечном итоге выяснил это сам. На самом деле он не возвращает true или false, скорее он возвращает первое вхождение в наборе или ноль, если этого не происходит.

И поскольку вы можете использовать это как условие (ноль обрабатывается как false, а не nil как true), это работает как хороший маленький хак для проверки, содержит ли строка букву.

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

(if (vowel? (first "abc"))
       (println "yay")
       (println "oops"))  ; => "yay"
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...