在F#中创建类或记录期间的自引用



我学习F#,并通过解决2018年代码降临节来完成。对于一项任务,我想写一个循环链表:每个节点都应该有到下一个和上一个节点的链接。一个节点的列表是有效的,该节点既是其自身的下一个节点,也是其自身的上一个节点。

这是我最初想到的记录:

type Node = {
mutable Next: Node
mutable Prev: Node
Value: int
}

但后来我发现,我无法实例化值为0并链接到其自身的初始Node。然后我试着写一个类,但仍然没能写出我需要的合法构造函数。这是我的尝试:

type Node(value: int, next: Node, prev: Node) as this =
let mutable _next = next
let mutable _prev = prev
let _value = value
private new value =
Node(value, this, this) // this line is illegal
member this.Next
with get() = _next
and set(value) = _next <- value
member this.Prev
with get() = _prev
and set(value) = _prev <- value
member this.Value
with get() = _value
static member Initial value =
Node(value)

以下是我想要实现的C#等价物:

public class Node {
public Node Next { get; set; }
public Node Prev { get; set; }
public int Value { get; }
public Node(int value, Node next, Node prev)
{
Value = value;
Next = next;
Prev = prev;
}

private Node(int value)
{
Value = value;
Next = this;
Prev = this;
}
public static Node Initial(int value)
{
return new Node(value);
}
}

我知道我可以只制作Node option类型的Next和Previ,但由于语法限制,这意味着我的代码会恶化。F#语法中应该缺少。试着在谷歌上搜索类似的问题,但没有成功。

在F#中创建记录或类的过程中,如何设置到自身的链接?

这可以通过以下方式使用具有可变字段的记录来实现:

type Node = {
mutable Next: Node
mutable Prev: Node
Value: int
}
with
static member CreateNew(value) = 
let node = 
{
Next = Unchecked.defaultof<_>
Prev = Unchecked.defaultof<_>
Value = value
}
node.Next <- node
node.Prev <- node
node
Node.CreateNew(1)

使用Unchecked.defaultof<_>可以绕过记录的正常非null性。在返回之前,请确保将其设置为非null。

最新更新