是否有编译器实现的原因,为什么记录不能具有AllowNullLiteralAttribute属性或者这是一个选择的约束?为什么F#记录不允许有AllowNullLiteralAttribute?
我确实看到这个约束强制更干净的代码有时但并非总是如此。
[<AllowNullLiteralAttribute>]
type IBTreeNode = {
mutable left : IBTreeNode; mutable right : IBTreeNode; mutable value : int}
with
member this.Insert x =
if x < this.value then
if this.left = null then
this.left <- {left = null; right = null; value = x}
else
this.left.Insert x
else
if this.right = null then
this.right <- {left = null; right = null; value = x}
else
this.right.Insert x
// Would be a lot of boilerplate if I wanted these public
[<AllowNullLiteralAttribute>]
type CBTreeNode(value) =
let mutable left = null
let mutable right = null
let mutable value = value
with
member this.Insert x =
if x < value then
if left = null then
left <- CBTreeNode(x)
else
left.Insert x
else
if right = null then
right <- CBTreeNode(x)
else
right.Insert x
增加了一个不可变版本的皱眉上的可变性人群。在这种情况下,速度大约快30%。
type OBTree =
| Node of OBTree * OBTree * int
| Null
with
member this.Insert x =
match this with
| Node(left, right, value) when x <= value -> Node(left.Insert x, right, value)
| Node(left, right, value) -> Node(left, right.Insert x, value)
| Null -> Node(Null, Null, x)
顺便说一下,有什么特别的原因,为什么你需要一个可变的树?我个人认为,不可变的语言会更加简洁,易于使用,而且在功能语言中更具惯用性。 – Juliet 2009-12-06 19:44:10
没有任何可变树会变得非常复杂。以上是一个简单的例子,但是当您试图实现插入和删除时,像没有重叠范围树的东西会变得混乱。如何处理删除级联节点或插入合并到多个其他节点的节点的情况。这种树结构本质上是可变的。 – gradbot 2009-12-06 20:24:07
“您如何处理删除级联节点或插入合并到多个其他节点的节点的情况。” - 只是为了funsies(也许也是为了rep讨价还价!),你问另一个关于如何将你的可变树转换为不可变树的问题。 – Juliet 2009-12-06 20:31:20