F#中的成员变量

时间:2014-01-10 18:31:08

标签: f#

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    member this.Eval = eval 5 10
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

这会调用eval 2次而不是一次。看来this.Eval是一个函数指针,每次调用.Eval时都会调用eval。

我真正想要的是变量。

我这样解决了......

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    let e = eval 5 10
    member this.Eval = e
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

如果我只想要一个成员变量而不是方法,这是否正确?

2 个答案:

答案 0 :(得分:2)

您描述的行为是.NET属性始终有效的方式,无论是在C#还是F#中。每次读取属性时都会评估属性的主体。

除了你的解决方案,这是正确的,我还要补充说,它会在Foo构造时计算出来。您可能只希望在第一次读取属性时计算值,如果是,您可以使用Lazy来执行此操作:

let eval a b = 
    let r = a + b
    printf "calculate.."
    r
type Foo() =
    // a lazy computation that will be evaluated the first time .Value is called
    let e = lazy eval 5 10
    member this.Eval = e.Value
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

答案 1 :(得分:2)

我认为更具风格的F#风格是:

type Foo() =
    let eval a b = 
        let r = a + b
        printf "calculate.."
        r
    let e = eval 5 10
    member this.Eval = e
[<EntryPoint>]
let main argv = 
    let f = Foo()
    let a = f.Eval
    let b = f.Eval
    0

即。你将eval放在类中,使用let绑定来隐藏实现