[英]How should I pass a String argument to clojure.core/apply
我有以下代碼:
(condp apply "string argument"
predicate1? "Result1"
predicate2? "Result2"
predicate3? "Result3"
"Else")
目前, "string argument"
在傳遞給apply時被解釋為seq,因此每個字符都成為謂詞的參數:
(apply predicate1? \s \t \r \i \n ...)
一個簡單的解決方案是將參數包裝在一個向量中:
(condp apply ["string argument"] ...)
我不確定這是非常慣用的。 有更好的解決方案嗎?
我認為沒有比直接使用cond
更具慣用性的方法,將“字符串參數”綁定到符號並將其傳遞給每個謂詞。 對於閱讀代碼的人來說,其他所有內容都會讓人感到困惑
使用以下輔助宏可以實現額外的魔力:
(defmacro pcond
"Translates clauses [pred result-expr] to a cond form:
(cond
(pred expr) result-expr
...)
A single result-expr can follow the clauses, and it will be appended
to the cond form under a generated test expression that returns logical
true."
[expr & clauses]
(let [expr-sym (gensym "expr")
else-kw (keyword (gensym "else"))
step (fn [[pred-form clause-form]]
(if (= else-kw clause-form)
[else-kw pred-form]
[(list pred-form expr-sym) clause-form]))
body (->> clauses
(partition 2 2 [else-kw])
(mapcat step))]
`(let [~expr-sym ~expr]
(cond ~@body))))
你可以這樣使用它
(pcond "String argument"
predicate1 "Result1"
predicate2 "Result2"
"Else")
它直接擴展到cond:
(clojure.core/let [expr13755 "String argument"]
(clojure.core/cond
(predicate1 expr13755) "Result1"
(predicate2 expr13755) "Result2"
:else13756 "Else"))
您可以使用匿名函數#(%1 %2)
來執行您要執行的操作。 IMO它比將condp
表達式包裝在一個向量中更好,但無論哪種方式都有效,也不是真正的直截了當。
(condp #(%1 %2) "string argument"
string? "string"
map? "map"
vector? "vector"
"something else")
;= Result1
編輯 (從評論中復制)
我不是宏的專家,但我一遍又一遍地聽到的是,如果一個函數會做,你不應該寫一個宏,而condp
提供了使用Clojure函數的所有元素。 一種不涉及宏並提高可讀性的方法可以定義一個函數(def apply-pred #(%1 %2))
並將其與condp
一起condp
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.