【发布时间】:2009-12-06 19:34:01
【问题描述】:
记录不能具有 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)
【问题讨论】:
-
顺便说一句,您需要可变树有什么特别的原因吗?我个人认为不可变的更简洁,更易于使用,并且在函数式语言中更惯用。
-
没有可变树的实现会变得非常复杂。上面是一个简单的案例,但是当您尝试实现插入和删除时,类似非重叠范围树的东西会变得混乱。如何处理删除级联节点或插入一个节点合并到多个其他节点的情况。这种树结构本质上是可变的。
-
"删除级联节点或者插入一个节点合并到多个其他节点的情况如何处理。" -- 只是为了好玩(也可能是为了卖淫!),你问另一个问题,关于如何将你的可变树转换成不可变树。
-
好的,给我几分钟,我会发布它。
标签: f# attributes nullable record