首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型定义中的“‘mutable”

类型定义中的“‘mutable”
EN

Stack Overflow用户
提问于 2010-02-08 17:50:06
回答 2查看 1.2K关注 0票数 4

为什么禁用的类型像这样

代码语言:javascript
复制
type t = A of int | B of string * mutable int

而这些类型是允许的:

代码语言:javascript
复制
type t = A of int | B of string * int ref
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2010-02-08 21:20:20

问题是,如何修改区分联合用例的可变元素的值?对于ref类型,这非常简单,因为ref是一个引用单元格(实际上是一个记录),它包含可变值:

代码语言:javascript
复制
match tval with
| B(str, refNum) -> refNum := 4

我们提取引用单元格,并将其分配给一个新的符号(或新变量) refNum。然后我们修改引用单元格中的值,这也修改了tval,因为对该单元格的两个引用(来自区分的联合用例和来自refNum变量)是别名的。

另一方面,当您编写let mutable n = 0时,您正在创建一个可以直接改变的变量,但是没有保存可变值的单元格--变量n是直接可变的。这显示了不同之处:

代码语言:javascript
复制
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值:

代码语言:javascript
复制
let foo() = 
  let mutable n = 0
  (fun () -> n <- n + 1; n) // error FS0407

我认为原因与歧视工会的情况是一样的(尽管在这种情况下不是那么明显)。编译器需要复制变量-它被存储为本地变量,并在生成的闭包中存储为字段。在复制时,您希望修改来自多个引用的同一变量,因此别名语义是唯一合理的做法……

票数 12
EN

Stack Overflow用户

发布于 2010-02-08 18:55:45

Ref是一个类型(int ref = ref<int>)。可变不是一个类型,它是一个允许你更新值的关键字。

示例:

代码语言:javascript
复制
let (bla:ref<int>) = ref 0 //yup
let (bla:mutable<int>) = 3 //no!
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2220651

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档