2024 年 Clojure 状态调查 中分享您的想法!

欢迎!请查看 关于 页面以获取有关此功能的更多信息。

+1
Clojure

我们在一个相当大的 Clojure 代码库上工作,我们遇到了很多这样的问题。

仅为说明,我们的设计是“一切皆映射”,这已经困扰了我们一段时间,并且有如下解决方案可以进行讨论

因此,我们使用 :keys, :strs 进行映射解构

(def my-func [{:keys [a b c] :as z}])

问题是,对于调用者来说,很难知道函数最终从 z 映射中使用了哪些内容(总是可以通过 get 获取比解构更多的内容。更糟的是,my-func 最终 elsewhere 将 z 传递出去,而无需查看 z 所在的所有位置就难以重构代码

而是有以下(命名现在不是很重要)

(def my-func [{:keys-only [a b c] :as z}])

仅从映射中提取 a b c,且 z 仅包含 a b c 键,这意味着函数有一个强有力的约定,说明该函数需要什么。不再有重构挑战

4 个回答

+1

您可以使用仅名称空间键,以增强代码库搜索的严格性(但您需要使用适当的解析进行搜索)。

与 select-keys 类似,移除键似乎是一种笨拙的工具。

如果你的首要目标是控制所有与数据流相关的事务,你可以考虑将数据处理置于类似多棱镜图(或难道是管道?)的监督之下。你需要的不仅仅是图/管道,但你已经理解了这个理念,可以自己建立一个适合自己的设施。作为麻烦的回报,你不仅可以得到“强制执行”,还能够获得有用的报告,比如表明x未被使用,或者自动排序处理步骤以生成可能的输出子集。

+1

简单地删除:as z可以吗?如果没有,就不能解构没有的东西。 ;)

当然,在少数情况下可以这样做 :)
0

你尝试使用spec了吗?

我当然检查过了spec。我本来期望这更像是语言结构而不是库。另外,我还没有深入研究spec,所以不知道上面的实现方式。我能想到的一种方法是

  (def my-func [m] (let [m (s/conform :spec m)]))

有更好的方法吗?
–2

我的规则是不允许使用:as

你无法强制执行它(尽管我认为一个检查器可以做到)。但它是我遵循的指导方针,以避免你提到的具体案例。

即使你有:keys-only,这也很难强制执行。虽然我个人很喜欢这个主意,所以给你点个赞。

我认为禁止:as是一个更简单的解决方案。因为有许多解构形式,你需要为它们所有都提供一个“only”变体。

也许不应该有:keys-only,而是可以选择:as-only或其他类似的方法,也许最好是称它为:into。因为这将适用于所有解构类型。
...