简体   繁体   English

F#中的成员变量

[英]Member variables in 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

This calls eval 2 times instead of one time. 这将调用eval 2次而不是一次。 It seems this.Eval is a function pointer that calls eval every time I call .Eval. 看来this.Eval是一个函数指针,每次我调用.Eval时都会调用eval。

What I really want to have is a variable. 我真正想要的是一个变量。

I solved it by doing this... 我这样做解决了...

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

Is this the correct way of doing this if I just want to have a member variable instead of method? 如果我只想拥有一个成员变量而不是方法,这是这样做的正确方法吗?

The behaviour you describe is the way .NET properties always work, whether in C# or F#. 您描述的行为是.NET属性始终起作用的方式,无论是在C#还是F#中。 The body of the property is evaluated each time the property is read. 每次读取属性时,都会评估属性的主体。

In addition to your solution, which is correct, I'd add that it calculates the value when Foo is constructed. 除了您的解决方案(是正确的)之外,我还要补充一点,它构造Foo时会计算值。 You might only want the value to be calculated when you read the property the first time, and if so you can use Lazy to do that: 您可能只希望在初次读取该属性时计算该值,如果是这样,则可以使用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

I think that the more idimatic F# style would be: 我认为更惯用的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

ie you put the eval inside the class with a let binding to hide the implementation 即您将eval放在带有let绑定的类中以隐藏实现

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM