我正在编写用于重新设计棋盘游戏的改版应用程序,其中我的棋盘结构包含一个单元格阵列,例如:
{... :board-cells [{:name "cell-1" :material #object} {:name "cell-2" :material #object} ...]}
虽然重新框架通过类似(db :board-cells)
的漂亮关键字语法来支持“自然”子结构的获取,但我已经厌倦了每次想要获取材料时都必须编写整个“向下钻取”查询的方法: (get (nth (db :board-cells) index) :material)
。这还具有将数据库的物理布局紧密耦合到应用程序逻辑的缺点。如果我决定更改数据库结构怎么办?然后,我必须更新十个不同的斑点,而不是一个。
是否有重新框架的正式方式来创建“虚拟查询”,所以我可以获得具有(db :get-nth-mat n)
之类的材料,其中n是board-cells
数组中的单元格编号?我以为db.cljs
和reg-sub
是我可以执行此操作的地方,但是它似乎不起作用。是的,我可以创建自己的吸气剂:
(defn get-material [db index]
(get (nth (db :board-cells) index) :material))
并像(println "mat-4=" (cell/get-material db 4))
那样称呼它,但这并不像(db :get-nth-mat n)
那样方便或友善
非常感谢。
db
只是一张地图,这个“功能”与它无关重新构图,但每个地图都是一个函数,关键字也是如此。所以当你[(map something)
或(:keyword something)you are actually doing
(获取地图内容)and
(获取某事:keyword)`。
因此,除了访问/迭代您的网页数据不同(例如doseq
,for
,map
,...)-假设您即将逐格渲染网格;这样您就摆脱了完全基于索引的访问。
否则,我会使用像您这样的专用功能,但宁愿命名material-by-idx
(在函数get
中命名和set
就像OO中的访问器(但也有类似的地方突变))。
具有正确命名的函数(最好是纯函数),可以完成一件事正确地是功能和Lisp的重要组成部分编程。通常,必须多输入一些缺点通过更高级别的编程范例(如局部线程化)缓解应用程序或在万不得已时使用宏。
并且您可以使用get-in
对其进行整理:
(defn material-by-idx [db idx]
(get-in db [:board-cells idx :material]))
Btw:您实际上想要的(db :get-nth-mat n)
版本可以(但不如您所愿)。它变成(get db :get-nth-mat
n)
(3个参数get
),如果没有键,则返回n
:get-nth-mat
中的db
。