3

我有一大堆懒​​惰的行要写入文件。在 C# 中,我会使用System.IO.File/WriteAllLineswhich 具有重载,其中行是string[]or 或IEnumerable<string>.

我想在运行时不使用反射来做到这一点。

(set! *warn-on-reflection* true)

(defn spit-lines [^String filename seq]
  (System.IO.File/WriteAllLines filename seq))

但是,我收到了这个反射警告。

反射警告,... - 无法解决对 WriteAllLines 的调用。

一般来说,出于性能原因,我需要知道何时需要反射,但我不关心这个特定的方法调用。我愿意编写更多代码以使警告消失,但不愿意将所有数据作为数组强制存储到内存中。有什么建议么?

4

1 回答 1

2

这里有两个可供考虑的选项,具体取决于您是否使用 Clojure 的核心数据结构。

从 LINQ将 seq 转换为IEnumerable<string>withEnumerable.Cast

此选项适用于IEnumerable仅包含字符串的任何内容。

(defn spit-lines [^String filename a-seq]
  (->> a-seq
       (System.Linq.Enumerable/Cast (type-args System.String))
       (System.IO.File/WriteAllLines filename)))

键入提示以强制调用者提供IEnumerable<string>

如果您想使用类型提示,请执行此操作。但是要注意,clojure 数据结构没有实现IEnumerable<String>,所以这可能会导致运行时异常

^|System.Collections.Generic.IEnumerable`1[System.String]|

将类型的完整 CLR 名称包装在垂直管道 ( |) 中,可以指定在 Clojure 语法中非法的字符。

(defn spit-lines [^String filename ^|System.Collections.Generic.IEnumerable`1[System.String]| enumerable-of-string]
  (System.IO.File/WriteAllLines filename enumerable-of-string))

(spit-lines "filename.txt" #{})这是将集合传递给类型提示版本时的异常:

System.InvalidCastException:无法将“clojure.lang.PersistentTreeSet”类型的对象转换为“System.Collections.Generic.IEnumerable`1[System.String]”类型。

有关指定类型的更多信息。

于 2014-10-30T17:13:27.930 回答