请在Clojure 2024 州情况调查中分享您的想法!

欢迎!请参阅关于页面了解有关该功能的一些更多信息。

+1
Clojure

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

仅此声明,我们的设计是“一切皆映射”,所以这已经困扰了我们一段时间,像下面的解决方案可能是可争论的

所以我们可以使用 :keys, :strs 来解构一个映射

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

问题是,对于调用者来说,很难知道函数最终使用了 z 映射中的哪些内容(人们总是可以用 get 一些比解构更多的东西。更糟糕的是,my-func 最终在其他地方传递 z 而且很难在不遍历 z 所去之处的情况下重构代码

取而代之的是,有如下(命名目前不重要)

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

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

4 个答案

+1

您可以使用仅名称空间键,以加强代码库搜索的严谨性(但您需要使用正确的解析来搜索)。

与 select-keys 类似,键的移除看起来像一个过于简化的工具。

如果您的主要目标是控制所有与数据流相关的问题,您可以考虑将数据处理放在类似 Prismatic Graph(或者是Plumbing?)的监督下。您需要的不仅仅是 Graph/Plumbing,但您可以得出这样的概念,并根据自己的需要进行设施。麻烦些来回,您可以获得不仅仅是“强制实施”,还有有用的报告,说明 x 未使用,或者自动排序处理步骤以产生可能的输出子集。

+1

仅仅移除:as z是否有效?没有内容就无法解构。 ;)

确实在某些情况下可以这样做 :)
0

你尝试过使用spec吗?

我确实检查了spec。我原本以为这将更多地是一种语言结构而不是库。另外,我对spec了解不多,所以我不知道怎么实现上述功能。我能想到的一种方法是:

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

有更好的方法吗?
–2

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

您无法强制执行它(尽管我想可能会使用代码核查器)。但是,这是一条我遵循的指导原则,以避免您提到的那种特定情况。

即使你有:keys-only,你也不可能真正强制执行它。话虽如此,我个人喜欢这个想法,所以给你点了个赞。

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

也许没有必要用:keys-only,一个更好的方案可能是使用:as-only或类似的,也许叫:into更好,因为这将适用于所有解构类型。
...