来自Java背景,我非常喜欢静态类型安全,并想知道clojure程序员如何处理数据格式定义的问题(可能不仅仅是类型而是一般不变量,因为类型只是一个特例.)
这类似于现有的问题"Clojure中的类型安全",但是更多地关注如何在编译时检查类型的方面,而我更关心如何解决问题.
作为一个实际例子,我正在考虑一个处理特定文档格式的编辑器应用程序.每个文档都包含几种不同的元素(图形元素,字体元素等).不同的元素类型都有编辑器,当然还有函数将文档转换为/到其本机的字节流 - 磁盘格式.
我感兴趣的基本问题是编辑器和读/写功能必须就通用数据格式达成一致.在Java中,我将文档的数据建模为对象图,例如,一个类代表一个文档,一个类用于每个元素种类.这样,我获得了关于数据结构的编译时保证,并且图形元素的字段"宽度"是整数而不是浮点数.它不保证宽度是正的 - 但使用getter/setter接口将允许相应的类添加这样的不变保证.
能够依赖于此使得处理此数据的代码更简单,并且可以在编译时或在运行时的早期捕获格式违规(其中一些代码尝试修改将违反不变量的数据).
如何在Clojure中实现类似的"数据格式可靠性"?据我所知,没有办法执行编译时检查并隐藏功能界面后面的域数据似乎不鼓励非惯用(或者我误解了?),那么Clojure开发人员做些什么才能感到安全传递给他们职能的数据格式?如何让代码尽快出错,而不是在用户再编辑20分钟并尝试保存到磁盘后,当保存功能注意到字体列表中有图形元素时编辑错误?
请注意我对Clojure和学习很感兴趣,但是还没有写任何实际的软件,所以我可能只是困惑而且答案很简单 - 如果是这样,抱歉浪费你的时间:) .
我没有看到使用验证API构建和操作数据有任何错误或不明确,如下所示.
(defn text-box [text height width]
{:pre [(string? text) (integer? height) (integer? width)]}
{:type 'text-box :text text :height height :width width})
(defn colorize [thing color]
{:pre [(valid-color? color)]}
(assoc thing :color color))
... (colorize (text-box "Hi!" 20 30) :green) ...
Run Code Online (Sandbox Code Playgroud)
此外,引用(变量,引用,原子,代理)可以具有关联的验证器函数,可以用于始终确保有效状态.
好问题 - 我也发现从静态类型语言转变为动态语言需要更加关注类型安全性.幸运的是,TDD技术在这里有很大帮助.
我通常会编写一个"验证"函数来检查您对数据结构的所有假设.对于不变的假设,我经常在Java中这样做,但在Clojure中它更重要,因为你需要检查类似于类型的思维.
然后,您可以通过以下几种方式使用validate函数:
(validate foo)(is (validate (new-foo-from-template a b c)))(read-foo some-foo-input-stream)是否有效如果您有一个复杂的数据结构,它是多个不同组件类型的树,您可以为每个组件类型编写一个验证函数,并为每个子组件的整个文档调用验证函数递归.一个很好的技巧是使用协议或多方法来使每个组件类型的验证函数具有多态性.
| 归档时间: |
|
| 查看次数: |
574 次 |
| 最近记录: |