是否可以使用Clojure引用函数存储的hashmap的值?

时间:2016-06-18 22:18:07

标签: clojure

让我们说我们有这样的事情:

(defstruct test :val :func)

(defn create-test 
  [] 
  (struct test 2 #(A)))

以某种方式可以引用:提供函数内部的val(即A所在的位置)?

2 个答案:

答案 0 :(得分:2)

这是循环引用问题的变体; lazy definitions allow the construction of these

虽然Clojure的方法不像链接的Haskell版本那么优雅,但是promise允许你在地图中放置一个对函数的惰性引用,然后在一个环境中为编译器定义函数。可以访问地图及其值:

(def knot-tying
  (let[{:keys[val func] :as knot} {:val "foo" :func (promise)}
       f (fn[](str val "bar"))]
    (deliver func f)
    knot))

((deref (:func knot-tying))) ;;=>"foobar"

或者,如果您希望将“向另一个方向”绑定并使该功能使用deref而不是deref

(def knot-tying-2
  (let[knot (promise)
       f (fn[] (str (-> knot deref :val) "bar"))
       tied {:val "foo" :func f}]
    (deliver knot tied)
    tied))

((:func knot-tying-2)) ;;=>"foobar"

答案 1 :(得分:1)

没有。给定一个对象,通常不可能找到哪些其他对象引用它。由于Clojure映射和函数是不可变的,因此必须首先创建函数然后创建映射,因此函数无法访问映射,除非它在创建后以某种方式传递给映射。

但是,假设您可以在另一个值之后创建函数,则可以允许函数使用closure直接访问值(但不包含包含的映射):

((:function
  (let [value 2
        function #(str "The value is: " value)]
    {:value value
     :function function})))
;=> "The value is: 2"