F# 记录:引用与可变字段

Alo*_*zcz 1 f# mutable data-structures

在重构我的 F# 代码时,我发现一条记录的字段类型为bool ref

type MyType =
  {
    Enabled : bool ref
    // other, irrelevant fields here
  }
Run Code Online (Sandbox Code Playgroud)

我决定尝试将其更改为mutable字段

// Refactored version
type MyType =
  {
    mutable Enabled : bool
    // other fields unchanged
  }
Run Code Online (Sandbox Code Playgroud)

另外,我应用了编译代码所需的所有更改(即更改:=<-、删除incrdecr函数等)。

我注意到更改后,一些单元测试开始失败。由于代码相当大,我无法真正看出到底改变了什么。

两者的实现是否存在显着差异,可能会改变我的程序的行为?

Fyo*_*kin 6

是,有一点不同。引用是一等值,而可变变量是一种语言构造。

或者,从不同的角度来看,您可能会说ref单元格是通过引用传递的,而可变变量是通过值传递的。

考虑一下:

type T = { mutable x : int }
type U = { y : int ref }

let t = { x = 5 }
let u = { y = ref 5 }

let mutable xx = t.x
xx <- 10
printfn "%d" t.x  // Prints 5

let mutable yy = u.y
yy := 10
printfn "%d" !u.y // Prints 10
Run Code Online (Sandbox Code Playgroud)

发生这种情况是因为xx是一个全新的可变变量,与 无关t.x,因此变异xx对 没有影响x

But是对与完全相同的引用单元格的yy引用,因此在通过引用它时将新值推入该单元格具有与通过 引用它相同的效果。u.yyyu.y

如果您“复制” a ref,则副本最终会指向相同的ref,但如果您复制可变变量,则仅复制其值。