正如其他人已经指出的那样,从技术上讲,StringConstant
它是一个只有一个案例的有区别的联合,您可以使用模式匹配来提取值。
在谈论F# 中的域建模时,我喜欢使用另一个有用的类比。通常,您可以从说某些数据类型是元组开始:
type Person = string * int
这是一种非常简单的数据表示方式,但问题是,当你编写 时"Tomas", 42
,编译器并不知道你的意思Person
,而是将它理解为string * int
元组。单例区分联合是命名元组的一种非常好的方法:
type Person = Person of string * int
这可能有点令人困惑,这是Person
两次使用该名称 - 第一次作为类型名称,第二次作为案例名称。这没有特殊含义 - 它只是意味着类型将与案例具有相同的名称。
现在你可以写Person("Tomas", 42)
来创建一个值,它会有一个 type Person
。您可以使用match
or对其进行分解let
,但您也可以轻松编写采用Person
. 例如,要返回名称,您可以编写:
let getName (Person(name, _)) =
name
我认为单例区分联合经常被使用主要是因为它们真的很容易定义并且很容易使用。但是,我不会在作为公共 API 公开的代码中使用它们,因为它们有点不寻常并且可能会造成混淆。
PS:还要注意提取值时需要使用括号:
// Correct. Defines symbols 'name' and 'age'
let (Person(name, age)) = tomas
// Incorrect! Defines a function `Person` that takes a tuple
// (and hides the `Person` case of the discriminated union)
let Person(name, age) = tomas