【问题标题】:overload dereference (!) and assignment (:=) operators in f#f# 中的重载取消引用 (!) 和赋值 (:=) 运算符
【发布时间】:2016-02-09 05:17:58
【问题描述】:

我正在尝试重载取消引用 (!) 和赋值 (:=) 运算符,但不是全局的。我仍然想保留通常的 ref op 重载。下面是一些代码来说明问题:

type MyVar<'a>(init:'a) =
    let mutable _value = init
    member __.Get() = _value
    member __.Set x = _value <- x
    //static member (!) (s:MyVar<'a>) = s.Get()      // compiles, doesn't work
    //static member (:=) (d:MyVar<'a>, s) = d.Set(s) // warning, doesn't work

//let inline (!) (x :MyVar<'a>) = x.Get()           // overrides !ref
//let inline (:=) (x :MyVar<'a>) (v :'a) = x.Set(v) // overrides ref := v 
let inline (!!) (x :MyVar<'a>) = x.Get()            // works but ugly
let inline (.=) (x :MyVar<'a>) (v :'a) = x.Set(v)   // works ... meh

let test_myvar() =
    let mv = new MyVar<_>("wee")
    let r = ref 100
    let x = !mv
    let y = !!mv
    let z = !r
    mv .= "haaa"
    r := 42

解决方案:

@Carsten 的解决方案是我一直在寻找和工作的。然而,事实证明,我使用的是 Websharper,它使用引号和 @Carstens 解决方案进行编译,变得有点 more complex。由于 Websharper.UI.Next 包含该解决方案,我只需将其包含在我的项目中,它就可以工作了!

【问题讨论】:

    标签: f# overloading operator-keyword


    【解决方案1】:

    您可以通过重载 (!)(:=) 操作符来使其与 static constraints 一起工作:

    type MyVar<'a>(init:'a) =
        let mutable _value = init
        member __.Value with get () = _value and set v = _value <- v
    
    let inline (!) a =
        (^a : (member Value : ^b) a)
    
    let inline (:=) a v =
        (^a : (member Value : ^b with set) (a, v))
    

    我删除了您的访问器,因为我只需要与 Ref&lt;'a&gt; 相同的访问器(但您可以重新添加它们)

    演示

    这是一个 F# 交互式会话,用您的价值观展示了这一点:

    val mv : MyVar<string>
    val r : int ref = {contents = 100;}
    
    > !mv;;
    val it : string = "wee"
    > !r;;
    val it : int = 100
    > mv := "It works";;
    val it : unit = ()
    > !mv;;
    val it : string = "It works"
    > r := 50;;
    val it : unit = ()
    > !r;;
    val it : int = 50
    

    备注

    我不确定我是否真的会这样做 - 你只会重新发明Ref-cell(作为一个班级)而一无所获,当然对于其他人来说可能很难阅读 - 所以要小心对待。

    【讨论】:

    • 这在 MyRef 有其他功能时很有用,例如我们在 UI.Next 中使用它来表示 reactive variables
    • 这就是我想要的。但是有一些并发症。见 OP。
    • 我现在明白你的意思了。我可以在 mv.Value
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-22
    • 2015-06-01
    • 2011-01-27
    相关资源
    最近更新 更多