gpt4 book ai didi

f# - 类型定义中的“可变”

转载 作者:行者123 更新时间:2023-12-03 18:27:58 29 4
gpt4 key购买 nike

为什么禁用类型像

type t = A of int | B of string * mutable int

虽然允许此类类型:
type t = A of int | B of string * int ref

最佳答案

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

match tval with
| B(str, refNum) -> refNum := 4

我们提取引用单元格并将其分配给一个新符号(或一个新变量) 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!)

因此,要回答您的问题 - 无法直接引用存储在受歧视联合案例中的值。您只能使用模式匹配来提取它,但这会将值复制到新变量中。这意味着您无法修改 mutable值(value)。

编辑
演示 mutable 的局限性F# 中的值,这里还有一个示例 - 您无法捕获 mutable闭包内的值:
let foo() = 
let mutable n = 0
(fun () -> n <- n + 1; n) // error FS0407

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

关于f# - 类型定义中的“可变”,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2220651/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com