首页 > 解决方案 > 无法更新结构中的可变字段?

问题描述

谁能告诉我为什么这个 Counter 结构不起作用?它总是在对 Incr 的调用之间将值重置为 0。

type Counter = 
    struct

        val mutable i: int 

        member public this.Incr() =
            this.i <- this.i + 1

        member public this.Count = 
            this.i
    end

let noCounty(s:string): int = 
    let x = new Counter()
    x.Incr()
    x.Incr()
    x.Count

标签: structf#mutable

解决方案


可变结构的语义总是令人困惑,因为在某些情况下,当您以某些方式使用它时,结构会被意外复制 - 所以避免结构内部的突变是个好主意。

您可以通过将x变量标记为noCountymutable 来完成这项工作。鉴于您当前对 的定义Counter,以下内容按预期工作:

let noCounty() = 
    let mutable x = new Counter()
    x.Incr()
    x.Incr()
    x.Count

我同意这很令人困惑。我认为逻辑是,如果您将变量定义为不可变,那么编译器会在进行任何可能改变它的调用之前将结构的值复制到一个新变量中。结果,编译后的代码看起来更像:

let noCounty () = 
    let x = new Counter()
    (let t1 = x in t1.Incr())
    (let t2 = x in t2.Incr())
    (let t3 = x in t3.Count)

我希望编译器会给我一些警告 - 所以在这种情况下可能缺少警告应该报告为编译器错误。(尽管这种行为可能是有意的。)


推荐阅读