我试图在F#中迭代IDictionary(稍后解释的原因......),并将每个值四舍五入到指定的精度。基本上这就是我想要做的事情:
List.iter (fun(x) -> a.Item(x) <- Math.Round(a.Item(x), input.precision)) (ICollectionToDoubleList a.Keys)
(其中ICollectionToDoubleList获取ICollection a.Keys并将其转换为双列表)。 但是,由于您无法在闭包内更改可变变量,因此无法编译。
我首次尝试解决方案是:
List.iter (fun(x) -> let p = Math.Round(a.Item(x), input.precision)
a.Item(x) := p
) (ICollectionToDoubleList a.Keys)
但是我收到了错误:
This expression was expected to have type
'a ref
but here has type
double
on a.Item(x)
我可以将IDictionary转换为两个列表(或元组列表),执行舍入,并重新转换为IDictionary,但这看起来有点混乱和错综复杂。
非常感谢任何指导。
编辑:
我忘了提到a被定义为:
let mutable (a : IDictionary<double,double>) = ...
答案 0 :(得分:2)
我想你想要
a.Item(x) <- p
在F#中,您使用<-
分配可变值,同时:=
分配给ref
值。
你甚至可以使用
a.[x] <- p
稍微简单的版本。
解释什么是可变的意思(它的行为与C中的const相反)
let mutable m = [|1|]
let t = [|1|]
m.[0] <- 0
t.[0] <- 0 //neither of these change m or t - only elements so they are fine
m <- [|1;2;3;|] //fine as m is mutable
t <- [|1;2;3;|] //not allowed as t is not mutable
如果您习惯于C中的const
,则上述内容大致相当于
int* m = {1};
const int* t = {1}
注意,两者都不等同于
const int* q const = {1}
这就是我认为你认为不可变的意思。
答案 1 :(得分:0)
好的,所以我发现了答案......
我已将a定义为:
let mutable (a : IDictionary<double,double>) = ...
如果我将其更改为
let (a : IDictionary<double,double>) = ...
然后这个编译。对我来说似乎有点反直觉,一个不可变的值可以被突变,但是一个可变变量不能!!