对F#中的静态字典感到困惑 [英] Confused about static dictionary in a type, in F#

查看:46
本文介绍了对F#中的静态字典感到困惑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用这种类型:

  type A ={S:字串}静态成员private l = Dictionary< string,A>()静态成员add s = A.l. [s]<-{S = s}静态成员列表()= l.Values 

如果我这样做:

  A.add"hello"A.添加世界" 

由于字典是静态的,我希望A.list()返回某些内容,但是它返回一个空列表.为什么会这样?

为了阐明我要执行的操作:我希望能够将类型A的对象注册到附加到类型本身的静态字典中,因为这会使对象存储库自包含"在某种程度上,

解决方案

您的 l 不是 field ,而是具有属性的 getter .

< p>与外观相反,属性"不是其中具有某些值的存储单元.财产"指的是财产".是一对get + set函数.只是功能,仅此而已.没有存储单元.

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

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

现在,为了制作一个存储单元(又称字段"),通常将使用静态成员val ,如下所示:

 静态成员val private l =字典< string,A>() 

不幸的是,在这种特殊情况下,这是行不通的,因为在F#记录和联合中不允许使用静态字段.它们可以在实际的类上正常工作,但不能在F#类型上工作.

因此,我建议将这些功能放在 module 中,而不是将它们设为静态方法:

 类型A = {S:字符串}模块A =let private l =字典< string,A>()让加s = l.[​​s]<-{S = s}let list()= l.值 

(只是一般而言:尝试使用更少的类以及更多的模块和函数;它们在F#中更惯用,并且通常导致更少的问题)

现在这可以按预期工作:

 >A.添加"hello";val it:单位=()>A.添加世界";val it:单位=()>一个列表();;val:Dictionary`2.ValueCollection< string,A>=seq [{S ="hello"};{S =世界"}] 

With this type:

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

if I do:

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

I'd expect A.list() to return something since the dictionary is static, but it returns an empty list. Why is that?

To clarify what I'm trying to do: I'd like to have the ability to register the objects of type A into a static dictionary that is attached to the type itself as it would make the object repository 'self contained' in the type, in a way.

解决方案

Your l is not a field, but a property with a getter.

A "property", contrary to appearances, is not a memory cell with some value in it. A "property" is a pair of get+set functions. Just functions, that's all. No memory cell.

So what you made yourself is a property with a getter (without a setter), and all that getter does is create a new Dictionary and return it.

This means, every time you access A.l, you get yourself a new, fresh dictionary. Because l is a function, not a memory cell.

Now, in order to make a memory cell (aka "field"), one would ordinarily use static member val, like so:

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

Unfortunately, in this particular case this doesn't work, because static fields are not permitted on F# records and unions. They work fine on actual classes, but not on F# types.

So instead what I would recommend is to put those functions in a module rather than making them static methods:

type A = { S: string }

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

(and just in general: try to use fewer classes and more modules and functions; they're more idiomatic in F# and lead to fewer problems in general)

Now this works as expected:

> 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" }]

这篇关于对F#中的静态字典感到困惑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆