为什么禁用类型喜欢
type t = A of int | B of string * mutable int
Run Code Online (Sandbox Code Playgroud)
虽然允许这样的类型:
type t = A of int | B of string * int ref
Run Code Online (Sandbox Code Playgroud)
Tom*_*cek 12
问题是,你如何修改受歧视的工会案件的可变元素的价值?对于ref
类型,这很容易,因为它ref
是一个包含可变值的引用单元格(实际上是一条记录):
match tval with
| B(str, refNum) -> refNum := 4
Run Code Online (Sandbox Code Playgroud)
我们提取参考单元格并将其分配给新符号(或新变量)refNum
.然后我们修改ref单元格中的值,它也会修改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!)
Run Code Online (Sandbox Code Playgroud)
所以,要回答你的问题 - 没有办法直接引用存在于受歧视的联合案例中的值.您只能使用模式匹配来提取它,但会将值复制到新变量.这意味着您无法修改该mutable
值.
编辑
为了演示mutable
F#中值的限制,这里还有一个例子 - 你无法捕获mutable
闭包内的值:
let foo() =
let mutable n = 0
(fun () -> n <- n + 1; n) // error FS0407
Run Code Online (Sandbox Code Playgroud)
我认为其原因与受歧视的工会案件相同(即使在这种情况下并不那么明显).编译器需要复制变量 - 它作为局部变量存储,并作为生成闭包中的字段存储.在复制时,你想要从多个引用修改相同的变量,所以别名语义是唯一合理的事情......
Ref是一个类型(int ref = ref<int>
).Mutable不是一个类型,它是一个允许您更新值的关键字.
例:
let (bla:ref<int>) = ref 0 //yup
let (bla:mutable<int>) = 3 //no!
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1074 次 |
最近记录: |