F# 与可变匹配
F# match with mutable
刚开始玩 F#,我想在我的应用程序中创建一些可变模型来玩,使用 F# discriminated union 而不是 class 层次结构。然而,似乎没有办法 "downcast" 一个受歧视的联合并且 "match with" 不会传播可变性。我该怎么办?
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 -> ()
你的问题是,你 match/deconstruct fb
变成了一个新的 pattern/value x : int
(这与 f.x
完全不一样! ) 当然是不可变的(默认情况下 F# 中的 bindings/values)。
如果您不给两者(值和模式)相同的名称,您可能会看得更清楚:
> 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
base-class with
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
会是 2
还是 1
? ;)
如何进行模式匹配/变异
使用
let fb = Foo {x = 1}
do match fb with
| Foo f -> f.x <- 2
| Bar -> ()
相反 - 这将从 fb
解构 f
然后你可以设置可变记录字段 f.x
但我建议不要通过尝试如何使用 mutable 值来开始学习 F# - 尝试尽可能多地使用 immutability 来学习尽你所能:)
刚开始玩 F#,我想在我的应用程序中创建一些可变模型来玩,使用 F# discriminated union 而不是 class 层次结构。然而,似乎没有办法 "downcast" 一个受歧视的联合并且 "match with" 不会传播可变性。我该怎么办?
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 -> ()
你的问题是,你 match/deconstruct fb
变成了一个新的 pattern/value x : int
(这与 f.x
完全不一样! ) 当然是不可变的(默认情况下 F# 中的 bindings/values)。
如果您不给两者(值和模式)相同的名称,您可能会看得更清楚:
> 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
base-class with
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
会是 2
还是 1
? ;)
如何进行模式匹配/变异
使用
let fb = Foo {x = 1}
do match fb with
| Foo f -> f.x <- 2
| Bar -> ()
相反 - 这将从 fb
解构 f
然后你可以设置可变记录字段 f.x
但我建议不要通过尝试如何使用 mutable 值来开始学习 F# - 尝试尽可能多地使用 immutability 来学习尽你所能:)