gpt4 book ai didi

F# - 如果更改则设置属性

转载 作者:行者123 更新时间:2023-12-04 17:33:59 24 4
gpt4 key购买 nike

我有一个类,它的属性有几个副作用,在调用它的 setter 时会触发,例如触发更改事件和/或呈现操作。我如何设计一个仅在其值需要更改时才设置该属性的函数?

有了裁判,我会做这样的事情:

let setIfChanged (oldVal: Ref<'T>) (newVal: 'T) = if newVal <> !oldVal then oldVal := newVal 
let y = ref 0
setIfChanged y 1

但是,可变属性不是引用,我似乎找不到任何方法来设计这样一个可以编译的东西。例如,
let setIfChanged oldVal newVal = if newVal <> oldVal then oldVal <- newVal 

只会告诉我 oldVal 是不可变的。

有没有办法注释 oldVal 以便它用于可变(可设置)属性?或者,还有更好的方法?

最佳答案

我认为没有任何简单的好方法可以“免费”做到这一点。

一个可能使这更容易的技巧是,您实际上可以将属性的 getter 和 setter 视为函数,因此您可以编写 setIfChanged作为具有两个函数的函数:

let setIfChanged getter setter v = 
if getter() <> v then setter(v)

给定一个类 A带属性(property) P ,然后您可以使用 set_P 调用它和 get_P作为参数:
let a = A()
setIfChanged a.get_P a.set_P 0
setIfChanged a.get_P a.set_P 1

编译器允许您访问 get_P 的事实和 set_P是一个鲜为人知的技巧——所以对很多人来说可能有点困惑。
为了完整起见,这里是 A 的定义我用来测试的:
type A() =
let mutable p = 0
member x.P
with get() = p
and set(v) = printfn "Setting!"; p <- v

更复杂的方法是使用引用和反射,这会更慢,但它会让你写出类似 setIfChanged <@ a.P @> 42 的东西。 .

关于F# - 如果更改则设置属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30469898/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com