似乎有多种方法可以在Clojure中实现数据模型:
(type ^{:type ::mytype} {:fieldname 1})get从映射中输入不存在的键会引发异常,而不是静默返回nil)我们已经达到了地图/列表不再适合我们的程度 - 我们遇到了很多错误,前置条件/后置条件很容易被捕获,但是需要花费很长时间来追捕(并且它是难以为接受嵌套地图/列表/向量的函数编写有效的前/后条件 - 但我们不确定上述哪一个可供选择.
我们有三个主要目标:
我们如何利用Clojure的力量来帮助我们?
Clojure 文化强烈支持原始数据类型。确实如此。但显式类型可能很有用。当你的普通数据类型变得足够复杂和具体时,你基本上就拥有了一个没有规范的隐式数据类型。
依赖构造函数。 从 OOP 的角度来看,这听起来有点肮脏,但构造函数只不过是一个安全、方便地创建数据类型的函数。普通数据结构的一个缺点是它们鼓励动态创建数据。因此,我尝试直接组合数据,而不是调用 (myconstructor ...)。如果我需要更改底层数据类型,那么很可能会出现错误以及问题。
记录是最佳选择。 由于对原始数据类型的大惊小怪,人们很容易忘记记录可以做很多地图可以做的事情。可以通过相同的方式访问它们。你可以对它们调用 seq 。您可以用同样的方式解构它们。绝大多数需要映射的函数也将接受记录。
元数据不会拯救你。 我对依赖元数据的主要反对意见是它没有体现在平等性上。
user> (= (with-meta [1 2 3] {:type :A}) (with-meta [1 2 3] {:type :B}))
true
Run Code Online (Sandbox Code Playgroud)
这是否可以接受取决于你,但我担心这会引入新的微妙错误。
其他数据类型选项:
协议非常有用,尽管它们感觉有点背离(函数+数据)范式。如果您发现自己在创建记录,您也应该考虑定义协议。
编辑:我发现了普通数据类型的另一个优点,这对我来说之前并不明显:如果您正在进行 Web 编程,则可以高效、轻松地在普通数据类型与 JSON 之间进行转换。(用于执行此操作的库包括 clojure.data.json、clj-json 和我最喜欢的 cheshire)。对于记录和数据类型,这项任务要麻烦得多。
| 归档时间: |
|
| 查看次数: |
808 次 |
| 最近记录: |