为什么禁用的类型像这样
type t = A of int | B of string * mutable int而这些类型是允许的:
type t = A of int | B of string * int ref发布于 2010-02-08 21:20:20
问题是,如何修改区分联合用例的可变元素的值?对于ref类型,这非常简单,因为ref是一个引用单元格(实际上是一个记录),它包含可变值:
match tval with
| B(str, refNum) -> refNum := 4我们提取引用单元格,并将其分配给一个新的符号(或新变量) refNum。然后我们修改引用单元格中的值,这也修改了tval,因为对该单元格的两个引用(来自区分的联合用例和来自refNum变量)是别名的。
另一方面,当您编写let mutable n = 0时,您正在创建一个可以直接改变的变量,但是没有保存可变值的单元格--变量n是直接可变的。这显示了不同之处:
let mutable a = 10
let mutable b = a
b <- 5 // a = 10, b = 5
let a = ref 10
let b = a
b := 5 // a = 5, b = 5 (because of aliasing!)所以,回答你的问题--没有办法直接引用存储在被区分的联合用例中的值。您只能使用模式匹配来提取它,但这会将该值复制到一个新变量中。这意味着没有任何方法可以修改mutable值。
编辑为了演示mutable值在F#中的局限性,这里还有一个示例--您不能在闭包中捕获mutable值:
let foo() =
let mutable n = 0
(fun () -> n <- n + 1; n) // error FS0407我认为原因与歧视工会的情况是一样的(尽管在这种情况下不是那么明显)。编译器需要复制变量-它被存储为本地变量,并在生成的闭包中存储为字段。在复制时,您希望修改来自多个引用的同一变量,因此别名语义是唯一合理的做法……
发布于 2010-02-08 18:55:45
Ref是一个类型(int ref = ref<int>)。可变不是一个类型,它是一个允许你更新值的关键字。
示例:
let (bla:ref<int>) = ref 0 //yup
let (bla:mutable<int>) = 3 //no!https://stackoverflow.com/questions/2220651
复制相似问题