Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure:如何模拟向流中的字符添加元数据?_Clojure_Metadata - Fatal编程技术网

Clojure:如何模拟向流中的字符添加元数据?

Clojure:如何模拟向流中的字符添加元数据?,clojure,metadata,Clojure,Metadata,由于有一个返回字符序列的函数,我需要修改它以允许将元数据附加到某些字符(但不是所有字符)。Clojure不支持基元类型上的“with meta”。因此,可能的选择是: 返回[字符,元数据]的向量序列; 优点:简单性、数据和元数据紧密相连 缺点:需要从矢量中提取数据 返回两个单独的seq,一个用于字符,一个用于元数据,如果调用方关心元数据,则会同时迭代这些seq; 优点:调用方不必从每个流元素中提取数据,如果愿意,可以丢弃元序列 缺点:需要同时迭代两个seq,如果需要元数据,则调用方的复杂

由于有一个返回字符序列的函数,我需要修改它以允许将元数据附加到某些字符(但不是所有字符)。Clojure不支持基元类型上的“with meta”。因此,可能的选择是:

  • 返回[字符,元数据]的向量序列;

    优点:简单性、数据和元数据紧密相连
    缺点:需要从矢量中提取数据
  • 返回两个单独的seq,一个用于字符,一个用于元数据,如果调用方关心元数据,则会同时迭代这些seq;

    优点:调用方不必从每个流元素中提取数据,如果愿意,可以丢弃元序列
    缺点:需要同时迭代两个seq,如果需要元数据,则调用方的复杂性会更高
  • 引入一些包含一个字符的记录包装器,并允许将元附加到自身(Clojure记录实现IMeta);

    优点:数据和元数据捆绑在一起
    缺点:需要从记录中提取数据
  • 你最好的选择

哪种方法更好?

使用向量/映射序列,例如

({:char 'x' :meta <...>} {:char 'y' :meta <...>} {:char 'z' :meta <...>} ...)
; or
(['x' <...>] ['y' <...>] ['z' <...>] ...)
使用解构绑定同时遍历字符和元数据也非常容易:

(doseq [{:keys [char meta]} s] ...)
; or
(doseq [[char meta] s] ...)
使用什么(地图或矢量)主要取决于个人喜好

在我看来,使用记录及其
IMeta
接口并不是很好:我认为这种元数据主要用于与语言相关的代码(宏、代码预处理、语法扩展等),而不是域代码。当然,我的这个假设可能是错误的


使用两个并行序列是最糟糕的选择,因为它不像单个序列那样方便界面用户。使用我上面写的函数丢弃元数据非常简单,如果所有序列都是惰性的,那么它甚至不会对性能产生影响。

谢谢。序列是非惰性的,因为它们很短并且总是经过完全处理。扔掉元数据很简单,但我也在考虑性能方面的问题。也许,使用记录来保存项目和元数据将是最快的方法,分解结构类似于地图?我没有意识到内置元数据不适用于域数据;当然,没有什么能阻止你将其用于你想要的任何目的。我只是认为,将它们用于语言级信息之外的其他内容不是很习惯用法。至于使用记录,可能会更快,因为记录被直接编译成带有相应字段的java类;您还可以使用类型对记录字段进行注释,以便它们甚至是正确的类型,而不是普通的
对象
。记录的使用将与地图的使用完全相同。@Tvaroh我想我对元数据的看法是错误的。在过去的两天里,我发现了一些代码示例,这些示例将元数据用于域逻辑。所以请忘记我刚才说的话。我仍然会使用显式结构来完成您的任务,但在您的情况下,元数据方法可能会更清晰。
(doseq [{:keys [char meta]} s] ...)
; or
(doseq [[char meta] s] ...)