提问人:user1443098 提问时间:4/27/2017 更新时间:4/27/2017 访问量:312
F# 从可变更改为 ref
F# Changing from mutable to ref
问:
正在处理需要可变集的程序。当尝试将集合放入闭包中时,我收到一个错误:
let mutable donefiles : Set<FileRecord> = Set.empty
let filestodo = Set.difference parms.FileSpecs donefiles
let errorFile (file: FileRecord) =
donefiles <- Set.add file donefiles
错误 40 可变变量“donefiles”以无效的方式使用。 可变变量无法通过闭包捕获。考虑消除 这种使用突变或使用堆分配的可变参考单元 通过 'ref' 和 '!'。
尝试将“donefiles”转换为引用,但似乎无法获得正确的语法。首先尝试了显而易见的(对我来说):
let donefiles : Set<FileRecord> = ref Set.empty
但:
错误 40 此表达式应具有类型 设置但这里有类型 'a ref
在这种情况下,我应该使用什么语法?
答:
4赞
Fyodor Soikin
4/27/2017
#1
首先,您似乎使用的是旧版本的 F#。F# 4.0 中取消了对可变变量的限制。
但是,如果您无法切换到较新的版本,以下是实际问题的答案:
该函数接受一个值并返回一个可变单元格。此类单元格的类型为 ,其中 是值的类型。ref
'a ref
'a
因此,在您的情况下,函数返回 ,但您专门注释为 type ,因此存在冲突(这是编译器告诉您的)。ref
Set<FileRecord> ref
donefiles
Set<FileRecord>
只需调整您的类型注释,它就会起作用:
let donefiles : Set<FileRecord> ref = ref Set.empty
要更改 ref 单元格,请使用运算符::=
donefiles := Set.add file !donefiles
评论
0赞
user1443098
4/27/2017
它几乎奏效了!通过您的更改(谢谢!)变量声明有效,但闭包定义无效:我收到错误“值不可变”。我试过了。然后我尝试了“!donefiles <- Set.add file donefiles”并得到“分配左侧的无效表达式”。donefiles <- Set.add file donefiles
0赞
user1443098
4/27/2017
donefiles := Set.add file !donefiles
工作(不得不去掉 var)
上一个:F# 理解循环 vars 可变?
评论
HashSet<FileRecord>
.ExceptWith
HashSet<T>