我越想到这个问题,看起来就越错误......
我在程序中定义了类似'map constructor'的东西。这背后的想法是我有一个通用的地图结构来处理一些“项目”,但我想对特定类型的项目强制执行一些默认值。
我遇到的问题是这个'map构造函数'有一个k-v对,并且该对的值应该由使用该映射的函数确定(在下面的例子中可能会更清楚)。
我的第一个想法是引用值中的表达式,然后在所述函数中对其执行eval
。第二个想法是用fn
替换值,但这似乎返回类似于引用的表达式。
让我试着描绘一下这个问题:
构造函数类似于
(defn cons-field [b]
{:a (fn [name] (str name "!"))
:b b
:c "default"})
项目已创建(def a-field (cons-field 5))
使用地图的调用函数类似于
(defn the-function [name field]
(str (get-in field [:a])))
现在我需要的是:a的值是'--function'中参数名称的函数。当然最后一个功能不起作用,我不确定它是否是正确的方法。 ':a'键并不总是fn
;有时它只是一个字符串文字。有什么想法吗?
干杯!
答案 0 :(得分:0)
所以这就是我在A. Webb和Jeremy Heiler的评论之后解决这个问题的方法。
初始构造函数已更改为:
(defn cons-field [b]
{:a nil ; either delete completely or comment that
; the case will be handled by the caller
:flag xx ; true or :case-qualifier
:b b
:c "default"})
调用函数已更改为:
(defn the-function [name field]
(let [case-q (:flag field)]
(cond
(= case-q :case-qualifier) (get-name name) ; you can have many different cases
; conciser using constants for these qualifiers
(...) ()))) ; else as normal
然后最初放入地图的逻辑进入不同的函数:
(defn get-name [name] (str name "!"))
希望这有助于其他人:)
答案 1 :(得分:0)
根据您发布的内容,无法真正理解您的问题。我能为你做的只是告诉你你提供的代码是做什么的,并猜测你希望它做什么。
(def r (cons-field 5))
创建哈希地图r
,(r :b)
= 5,(r :c)
=“默认”和(r :a)
= (fn [name] (str name "!"))
。如您所见,(r :a)
的结果和(r :c)
的结果都与r或5无关。
如果上面描述的结果是您想要的,那么进行一些重构是合乎逻辑的:
(def default-field {:a (fn [name] (str name "!"))
:c "default"})
(def cons-field (partial assoc default-field :b))
关于the-function
:对(get-in field [:a])
的调用与(field :a)
相同,并返回函数(fn [name] ...)
。 the-function
将使用str对此fn进行字符串化,并且很可能会返回类似“user.fn $ 23092 ....”的内容。
如果您希望the-function
返回调用(fn [name] ...)
的结果并将名称传递给该函数,则需要按如下方式更改the-function
:
(defn the-function
[name field]
(str ((field :a) name)))
如果你希望the function
根据a的实际值返回其他内容,你可以检查它是否是一个函数并用名称调用它,否则返回值。
(defn the-function
[name field]
(when-let [v (field :a)]
(or (when (fn? v)
(v name))
v)))
现在从你自己的答案中读到我对你想要解决的实际问题更加困惑,但我希望这个答案可以提供帮助。