让我们说我们有这样的事情:
(defstruct test :val :func)
(defn create-test
[]
(struct test 2 #(A)))
以某种方式可以引用:提供函数内部的val(即A所在的位置)?
答案 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"