对 F# 中的字段及其访问规则以及初始化非常困惑

Tho*_*mas 5 f#

让我们上这堂课:

type Test() =

    let mutable Flag1 : bool = false
    [<DefaultValue>] val mutable Flag2 : bool

    do
        Flag1 <- true  // that works
        Flag2 <- true  // nope... why?

    member this.SetFlag =
        Flag1 <- true  // no 'this' instance? does that mean it's static?
        this.Flag2 <- true  // that works now, but still no way to set a default value
Run Code Online (Sandbox Code Playgroud)

[<DefaultValue>]当我希望能够将值设置为我自己的任何值时,为什么我需要?

然后现在:

type Test2() =
    Inherit(Test)

    do
        Flag1 <- true  // not accessible
        Flag2 <- true  // not happening either

    member this.SetFlag2 =
        Flag1 <- true  // not accessible
        this.Flag2 <- true  // ok
Run Code Online (Sandbox Code Playgroud)

所以我可以这样做:

    member val Flag1 : bool with get, set
Run Code Online (Sandbox Code Playgroud)

但是为什么语法val this.Flag1不是实例的一部分呢?而且..我无法从构造函数访问它。

谁能解释一下这是如何工作的?因为它很混乱。如果你不能在那里设置东西,看起来构造函数的用处很低。或者,我错过了什么?而且我无法通过 new() 构造函数构造类的实例并设置变量,因为最后一条语句需要返回该实例,所以我无法创建实例,设置我需要的所有内容然后返回它。或者,有可能吗?

另外,我怎么能有一个字段:

  • 是一个实例字段,不是静态的
  • 我可以在构造函数中初始化为任何我想要的
  • 是可变的
  • 可从成员函数访问

本质上就像 C# 中的一个普通字段。

我试图实现的是:我需要有一个属于类实例的计时器对象,并且可以在构造函数中进行初始化。类方法需要访问计时器,而计时器的回调需要访问类字段。

在伪 C# 中,我会有这样的事情:

Class A
{
    public Timer MyTimer;
    public bool Flag1, Flag2;

    A()
    {
        MyTimer = new Timer(Callback);
    }

    public void StartTimer()
    {
        MyTimer.Start();
    }

    public void Callback()
    {
        if (Flag1) Flag2 = true;
    }
}

public class B : A
{
    public void DoStuff()
    {
        Flag1 = True;
    }
}
Run Code Online (Sandbox Code Playgroud)

小智 0

您需要的是为其所有主体指定一个类型实例别名:

type Test() (*here is the part you need: *) as this = 
    // ...
    // and then you can access your public mutable field by type instance alias:
    do this.Flag2 <- true
Run Code Online (Sandbox Code Playgroud)

此外,在第二个继承类 ( Test2 ) 中,您可以使用相同的语法访问Flag2字段。而且,顺便说一下,Field1无法在Test2类中访问,因为它是私有的,因为您已经使用let绑定定义了它