Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/logging/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure中的重载关键字_Clojure - Fatal编程技术网

Clojure中的重载关键字

Clojure中的重载关键字,clojure,Clojure,我有一张这样的地图: (def a {:a 1, :b 2}) :我希望重载映射,以便某些关键字执行函数,以便: (c: a) (str (:c (enrich ab)) " " (:c (enrich ab)) " " (:c (enrich ab))) 可以执行一个函数。这可能吗 更新: 我确实意识到我可以做以下事情: (def a {:a (fn[] 1) :b (fn[] 2) :c (fn[] x)}) :及: :但我必须将现有的每个地图条目转换为函数 我希望每次都“重新评估”

我有一张这样的地图:

(def a {:a 1, :b 2})
:我希望重载映射,以便某些关键字执行函数,以便:

(c: a)
(str (:c (enrich ab)) " " (:c (enrich ab)) " " (:c (enrich ab)))
可以执行一个函数。这可能吗

更新: 我确实意识到我可以做以下事情:

(def a {:a (fn[] 1) :b (fn[] 2) :c (fn[] x)})
:及:

:但我必须将现有的每个地图条目转换为函数

我希望每次都“重新评估”函数。例如,当我这样做时:

(def ab{:a 1         :b 2         :c ( #(.nextInt (java.util.Random.) 1000))}) 

(str (:c ab) " " (:c ab) " " (:c ab))
我得到:

61 61 61
而不是三个不同的数字

更新2 我考虑了我得到的答案,意识到他是对的,我应该只使用不变的结构。我提出的最后一个解决方案是拥有一个“丰富”功能,可以根据需要创建动态属性

 (def a {:a 1, :b 2})
:我希望重载映射,以便某些关键字执行函数,以便:

(c: a)
(str (:c (enrich ab)) " " (:c (enrich ab)) " " (:c (enrich ab)))
每次将生成不同的数字,如下所示:

58 639 710

在我看来,使用同一个映射有时传回不可变值,有时传回不纯函数似乎违背了不可变映射应该用于的精神。与其这样做,我建议使用一个引用类型,它指向一个只有数据值的不可变映射。然后,当其中一个数据值需要不同时,将引用类型指向反映任何更改的新不可变映射。

我相信,如果将数据结构设置为记录而不是常规映射,则可以覆盖关联查找的行为

您基本上需要覆盖clojure.lang.ILookup:有关更多详细信息,请参阅

下面是一个简单的例子:

(deftype TestLookup []
  clojure.lang.ILookup
    (valAt [this k not-found]
      (str "Generated value for key - " k))

    (valAt [this k]
      (.valAt this k nil)))

(def lookupable-object (TestLookup.))

(:somekey lookupable-object)
=> "Generated value for key - :somekey"

Clojure更喜欢纯数据结构,而不是结合数据和行为的对象。通过函数访问数据结构,可以获得所需的行为:

(def base-foo {:a 1, :b 2})

(defn foo [key]
  (if (= :c key) 
    (rand-int 100)
    (get base-foo key)))

(str (foo :c) " " (foo :c) " " (foo :c))

;;=> "66 52 25"

我希望在访问字段时对函数求值,因为返回的值是计算出来的,并且可以更改。我知道这并不是像我的简单示例所示的那样是不变的,但我只是展示了一个简单的案例哦,好吧,所以你要计算的函数不是纯函数。是的,对不起,我没有提到,在我最初的问题中,我尝试过这个,但它不允许我将项目关联到其中。我选择了你的答案,尽管我可能无法使用它,因为我对你试图这么做印象深刻:)