F#从mutable变为ref

时间:2017-04-27 12:50:38

标签: reference f# mutable

处理需要可变集的程序。当试图将该集合置于闭包中时,我得到一个错误:

let mutable donefiles : Set<FileRecord> = Set.empty
let filestodo = Set.difference parms.FileSpecs donefiles
let errorFile (file: FileRecord) =
    donefiles <- Set.add file donefiles
  

错误40可变变量&#39; donefiles&#39;以无效的方式使用。   闭包不能捕获可变变量。考虑消除   这种突变的使用或使用堆分配的可变参考单元   通过&#39; ref&#39;和&#39;!&#39;。

尝试转换&#34; donefiles&#34;进入参考,但似乎无法使语法正确。首先尝试了显而易见的(对我而言):

let donefiles : Set<FileRecord> = ref Set.empty

但:

  

错误40此表达式应具有类型       设置但这里有类型       &#39;参考

在这种情况下我应该使用什么语法?

1 个答案:

答案 0 :(得分:4)

首先,似乎您使用的是旧版本的F#。对可变变量的限制was lifted in F# 4.0

但是如果您无法切换到更新的版本,这里是实际问题的答案:

函数ref获取一个值并返回一个可变单元格。此类单元格的类型为'a ref,其中'a是值的类型。

因此,在您的情况下,ref函数返回Set<FileRecord> ref,但您明确注释donefilesSet<FileRecord>类型,因此存在冲突(这就是编译器告诉你)。

只需调整您的类型注释,它就可以工作:

let donefiles : Set<FileRecord> ref = ref Set.empty

要改变ref单元格,请使用:=运算符:

donefiles := Set.add file !donefiles