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

欢迎!请查阅 关于 页面以获取更多关于如何使用本网站的信息。

+1
Clojure

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

以下免责声明,我们的设计是“一切都是一个 map”,因此这个问题困扰了我们相当长的一段时间,并可能对以下解决方案产生争议:

因此,我们有 :keys, :strs 用于解构 map

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

问题是,对于调用者来说,很难知道最终会从 z map 中使用哪些函数(人们始终可以get解构中的某种东西。更糟糕的是,my-func 及其他地方仍在传递 z,这使得难以在不经过每个 z 的位置重构代码。

相反,可以使用以下(现在的命名并不重要)

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

它只从 map 中提取了 a b c,并且 z 只包含 a b c 键,这意味着函数有一个强合同,说明此函数需要哪些内容。不再有重构挑战

4 个答案

+1

您可以使用仅命名的命名空间键,以满足对代码库搜索的严格性(但您必须使用适当的解析进行搜索)。

与 select-keys 一样,删除键的运算看起来像是用钝器处理。

如果您的首要目标是控制所有与数据流相关的问题,那么您可以考虑将数据处理置于类似 Prismatic Graph(或它是否是 Plumbing?)的监督之下。您需要的不仅仅是 Graph/Plumbing,但您可以得到这个想法,并创建自己的设备来满足需求。通过这个麻烦,您不仅可以获得“强制执行”,还可以得到有关 x 未使用的有用报告,甚至可以自动对处理步骤进行排序,以产生可能的输出子集。

+1

仅仅删除:as z能够奏效吗?无法解构你所没有的东西。 ;)

当然在少数情况下可以奏效 :)

你尝试使用spec了吗?



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

有更好的方法吗?

我的规则是禁止使用:as

你无法强制执行(尽管我认为linters可以)。但这是我遵循的指南,以避免你提到的情况。

即使在您启用了:keys-only的情况下,您也无法真正强制执行它。话虽如此,我个人很喜欢这个想法,所以您获得了我的支持。

by
尽管如此,我认为禁止:as是一个更简单的解决方案。因为存在许多形式的解构,您需要为每个形式提供一个“仅”变体。

也许,不是有:keys-only,更好的方法是有:as-only或者类似的东西,也许最好称其为:into。因为这将适用于所有解构类型。
...