对F#中类型中的静态字典感到困惑

  • 本文关键字:字典 静态 类型 f#
  • 更新时间 :
  • 英文 :


使用此类型:

type A =
{
S: string
}
static member private l = Dictionary<string, A>()
static member add s = A.l.[s] <- { S=s }
static member list () = l.Values

如果我这样做:

A.add "hello"
A.add "world"

我希望A.list((返回一些东西,因为字典是静态的,但它返回一个空列表。为什么?

为了澄清我想做的事情:我希望能够将类型A的对象注册到一个静态字典中,该字典附加到类型本身,因为在某种程度上,它会使对象存储库"自包含"在类型中。

您的l不是字段,而是带有getter的属性

A";属性";,与外表相反,它不是一个具有某种价值的存储单元;属性";是一对get+set函数。只是功能,仅此而已。没有存储单元。

因此,您自己创建的是一个带有getter(没有setter(的属性,而getter所做的只是创建一个新的Dictionary并返回它

这意味着,每次访问A.l时,您都会获得一本全新的词典。因为l是一个函数,而不是一个存储单元。

现在,为了制作一个存储单元(又称"字段"(,人们通常会使用static member val,就像这样:

static member val private l = Dictionary<string, A>()

不幸的是,在这种特殊情况下,这不起作用,因为F#记录和联合中不允许使用静态字段。它们在实际类上运行良好,但在F#类型上则不然。

因此,我建议将这些函数放在模块中,而不是使它们成为静态方法:

type A = { S: string }
module A =
let private l = Dictionary<string, A>()
let add s = l.[s] <- { S=s }
let list () = l.Values

(一般来说:尽量使用更少的类、更多的模块和函数;它们在F#中更惯用,通常会导致更少的问题(

现在这工作如预期:

> A.add "hello";;
val it : unit = ()
> A.add "world";;
val it : unit = ()
> A.list();;
val it : Dictionary`2.ValueCollection<string,A> =
seq [{ S = "hello" }; { S = "world" }]

最新更新