【问题标题】:Overloading keywords in ClojureClojure 中的关键字重载
【发布时间】:2011-04-07 15:45:36
【问题描述】:

我有一张这样的地图:

(def a {:a 1, :b 2})

:我希望重载地图,以便某些关键字执行功能,以便:

(c: a)

可以执行一个函数。这可能吗?

更新:

我确实意识到我可以这样做:

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

:和:

((c: a))

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

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

(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})

:我希望重载地图,以便某些关键字执行功能,以便:

(str (:c (enrich ab)) " " (:c (enrich ab)) " " (:c (enrich ab)))

每次都会产生不同的数字,如下所示:

58 639 710

【问题讨论】:

    标签: clojure


    【解决方案1】:

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

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

    这是一个简单的例子:

    (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"
    

    【讨论】:

    • 我确实尝试过,但它不允许我将项目关联到其中。我选择了你的答案,即使我可能无法使用它,因为你真的尝试过这样做给我留下了深刻的印象:)
    【解决方案2】:

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

    【讨论】:

    • 我希望在访问该字段时评估该函数,因为返回的值是计算出来的并且可以更改。我知道这不是我的简单示例所示的不可变的,但我只是展示了一个简单的案例
    • 哦,好的,所以您要评估的函数不是纯函数。
    • 是的,抱歉,我在最初的问题中没有提到这一点
    【解决方案3】:

    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"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-09-13
      • 2011-05-01
      相关资源
      最近更新 更多