【问题标题】:Access a global variable by its name in Clojure在 Clojure 中通过名称访问全局变量
【发布时间】:2013-07-06 09:03:12
【问题描述】:

我正在尝试使用 clojure 进行文本冒险。

这是我苦苦挣扎的地方:

(ns records)


(defrecord Room [fdesc sdesc ldesc exit seen])

(defrecord Item [name location adjective fdesc ldesc sdesc flags action ])

(def bedroom (Room. "A lot of text."
                    nil
                    "some text"
                    '(( "west" hallway wearing-clothes? wear-clothes-f))
                    false))

(def hallway (Room. "description of room."
                            nil
                           "short desc of room."
                           '(("east" bedroom) ("west" frontdoor))
                           false))

(def location (ref bedroom))

(defn in?
  "Check if sequence contains item."
  [item lst]
  (some #(= item %) lst))

(defn next-location
  "return the location for a entered direction"
  [direction ] 
  (second (first (filter #(in? direction %) (:exit @location)))))

(defn set-new-location
  "set location parameter to new location."
  [loc]
  (dosync (ref-set location loc)))

我的问题是更新 var 位置。

如果我输入 (set-new-location hallway) 它可以正常工作。位置设置为新房间,我可以访问它的字段。但是,我需要做的是从房间的出口字段读取下一个可能的出口,但是当我输入(set-new-direction (next-exit "west")) 时,位置说走廊,但它没有指向变量“走廊”。

在 CL 中,我会使用(符号值走廊)。如何在 Clojure 中做到这一点?

编辑:我真的很想使用 var-per-location,因为我已经勾勒出了大约 30 个位置,每个位置有 20 条线,因此放在一张地图上太笨拙了。

【问题讨论】:

    标签: clojure


    【解决方案1】:

    您可以将@(resolve sym) 用作symbol-value 类似工作;它实际上所做的是在当前命名空间中查找由符号 sym 命名的 Var(可能是使用 use / require :refer 引入的 Var)并提取其值。如果您想控制查找 Var 的命名空间,请参阅 ns-resolve

    您也可以不使用 Var-per-location,而是将您的位置存储在地图中的某个地方:

    (def locations {:hallway ... :bedroom ...})
    

    (您也可以将此地图放在 Ref 中,以便在运行时添加新位置。)

    【讨论】:

    • 这应该如何工作?如果我尝试(ref-set location @(resolve bedroom)),我会得到ClassCastException records.Room cannot be cast to clojure.lang.Symbol clojure.core/ns-resolve (core.clj:3954)
    • 您需要说@(resolve 'bedroom)(注意引号)才能将符号bedroom 传递给resolve。当然,如果你硬连线这样一个特定的符号,那么这样做是没有意义的,你可以写bedroom;但如果符号是动态计算的,例如调用next-location,则无需额外引用:@(resolve (next-location "west"))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-10-11
    相关资源
    最近更新 更多