F#中创建class或记录时的自引用
Self-reference during the creation of class or record in F#
我学习 F# 并通过解决 Advent of Code 2018 来做到这一点。对于 one task 我想写一个循环的 linked 列表:每个节点应该有 links 到下一个和上一个节点。一个节点的列表是有效的,该节点既是其自身的下一个又是其前一个。
这是我最初想出的记录:
type Node = {
mutable Next: Node
mutable Prev: Node
Value: int
}
但是后来我发现我无法实例化值为0和links的初始节点本身。然后我尝试写一个class,但仍然没有写出我需要的合法构造函数。这是我的尝试:
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);
}
}
我知道我可以将 Next 和 Prev 设为 Node option
类型,但这意味着由于语法限制而使我的代码变得更糟。 应该 是我遗漏的 F# 语法中的某些内容。尝试谷歌搜索并搜索类似的问题,但无济于事。
如何在创建记录期间将 link 设置为自身或在 F# 中设置 class?
这可以通过以下方式使用具有可变字段的记录来实现:
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<_>
绕过记录的正常不可空性。只需确保在 return.
之前将其设置为非空值
我学习 F# 并通过解决 Advent of Code 2018 来做到这一点。对于 one task 我想写一个循环的 linked 列表:每个节点应该有 links 到下一个和上一个节点。一个节点的列表是有效的,该节点既是其自身的下一个又是其前一个。
这是我最初想出的记录:
type Node = {
mutable Next: Node
mutable Prev: Node
Value: int
}
但是后来我发现我无法实例化值为0和links的初始节点本身。然后我尝试写一个class,但仍然没有写出我需要的合法构造函数。这是我的尝试:
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);
}
}
我知道我可以将 Next 和 Prev 设为 Node option
类型,但这意味着由于语法限制而使我的代码变得更糟。 应该 是我遗漏的 F# 语法中的某些内容。尝试谷歌搜索并搜索类似的问题,但无济于事。
如何在创建记录期间将 link 设置为自身或在 F# 中设置 class?
这可以通过以下方式使用具有可变字段的记录来实现:
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<_>
绕过记录的正常不可空性。只需确保在 return.