提问人:Sylverblack 提问时间:2/20/2022 更新时间:2/20/2022 访问量:109
区分联合中的可变内部值
Mutable internal value in discriminated union
问:
任务是创建一个二叉树,其节点具有一个可以是 true 或 false 的成员,以及一个应设置为 true 的方法(如果尚未设置为 true)。is_locked
lock()
is_locked
我试过了这个
type BinaryTreeNode =
| Node of BinaryTreeNode * BinaryTreeNode
| End
with
let mutable internalIsLocked = false
member this.is_locked
with get() = internalIsLocked
member this.lock() = internalIsLocked <- true
但是编译器由于 AT LET 绑定而说不。This declaration element is not permitted in an augmentation
val mutable internalIsLocked : bool
相反,出于同样的原因不起作用。
那么这个问题该如何解决呢? 难道不能用受歧视的工会来解决吗?
答:
1赞
Brian Berns
2/20/2022
#1
如果确实想这样做,可以将可变状态移动到单独的类类型中,然后在可区分的联合中使用该类型:
type Lock() =
let mutable internalIsLocked = false
member this.is_locked
with get() = internalIsLocked
member this.lock() = internalIsLocked <- true
type BinaryTreeNode =
| Node of Lock * BinaryTreeNode * BinaryTreeNode
| End
with
static member Create(left, right) =
Node (Lock(), left, right)
member this.Lock =
match this with
| Node (lock, _, _) -> Some lock
| End -> None
请注意,我假设节点是不可锁定的。用法:End
let node = BinaryTreeNode.Create(End, End)
node.Lock.Value.is_locked |> printfn "%A" // false
node.Lock.Value.lock()
node.Lock.Value.is_locked |> printfn "%A" // true
但是,我不推荐它。
评论
0赞
Sylverblack
2/20/2022
谢谢你的回答。你会推荐什么?普通班级?
0赞
Brian Berns
2/20/2022
这取决于为什么需要锁定节点。一般来说,我更喜欢不可变的数据结构。
0赞
Sylverblack
2/20/2022
我应该补充一点,这个任务来自我想解决的编码面试。如果可能的话,我也会尽量避免可变性。
上一个:创建持久性数组
下一个:F# 记录:ref 与可变字段
评论