F# 与可变匹配

标签 f#

刚开始玩 F#,我想在我的应用程序中创建一些可变模型来玩,使用 F# 区分联合而不是类层次结构。然而,似乎没有办法“贬低”一个有区别的联合,并且“匹配”不会传播可变性。我该怎么办?

type Foo = {
    mutable x: int
}

type FooBar = 
    | Foo of Foo
    | Bar

let f = {x = 2};
do f.x <- 3; //All ok

let fb = Foo {x = 1}
do match fb with
    | Foo {x = x} -> x <- 2 //"This value is not mutable"
    | Bar -> ()

最佳答案

你的问题是,你匹配/解构 fb进入一个新的模式/值x : int (这与 f.x 完全不同!)当然是不可变的(因为 F# 中的绑定(bind)/值是默认设置的)。

如果您不给(值和模式)都赋予相同的名称,您可能会更好地看到这一点:

> match fb with Foo { x = y } -> y;;
val it : int = 1

看你比赛x反对y所以y将得到 x 的值(但不会是可变的)
C#中的情况

让我们看看 C# 中的类似情况

假设你有一个 Foo类(class):
class Foo { public int x { get; set; } }

FooBar基类
class Foo2 : FooBar 
{ 
    public Foo Value { get; } 
}

(我删除了 ctors,因为我很懒 - 你明白了)

现在你会这样做:
var fb = new Foo2(new Foo(1));
var x = fb.Value.x;
x := 2;

你认为fb.Value.x将是 21 ? ;)

如何进行模式匹配/变异

采用
let fb = Foo {x = 1}
do match fb with
    | Foo f -> f.x <- 2
    | Bar -> ()

相反 - 这将解构 ffb然后您可以设置可变记录字段f.x
但我建议不要通过尝试如何使用可变值来开始学习 F# - 尝试使用 来学习不变性尽可能多地:)

关于F# 与可变匹配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30627443/

相关文章:

ios - 我可以使用 F# 构建(跨平台)库以在其他 native iOS 应用程序中使用吗?

f# - F# Async.Parallel 结果是否保证有序?

F# 递归类型到 SQL 表

f# - 声明变量而不分配解决方法

javascript - F# 到 JavaScript 编译器的 F# 项目模板

.net - 如何使用 F# 将文件读入内存集合?

arrays - 使用 F# 中的 Npgsql 传入和传出 postgresql 存储过程的数组参数

csv - 在 F# 中使用 CsvProvider

c# - 如何在 C# 中复制 F# 区分的联合类型?

winforms - Windows 窗体中自定义控件的问题