如果我正常工作,它会按预期工作(缓存结果):
let help = let tmp = printfn "oh no"
1+1
fun () -> tmp
help ()
help ()
>oh no
但是,如果我将其作为成员函数,它将不再有效:
type test =
{ a: float }
member x.help =
let tmp = printfn "oh no"
x.a * 2.
fun () -> tmp
member x.b = x.help ()
let t = { a = 1. }
t.b
t.b
>oh no
>oh no
答案 0 :(得分:3)
正如@John所说,根据F# specification,您的help
财产相当于
type test =
{ a: float }
member x.help with get () =
let tmp = printfn "oh no"
x.a * 2.
fun () -> tmp
这是伪装的函数,因此每次调用属性时都会计算一个新的tmp
值。
要确保一次调用该属性,您可以创建一个私有帮助器并在类型扩充中使用它:
type test = { a: float }
/// Create a private helper to make sure 'help' is evaluate once
let private help =
printfn "oh no"
fun x -> x.a * 2.
/// Create a property using the private helper
type test with
member x.b = help x
答案 1 :(得分:2)
这是真正的区别 -
let help = let tmp = printfn "oh no"
1+1
fun () -> tmp
printfn "here"
help ()
help ()
打印
here
oh no
所以,在它被召唤之前,实际上已经形成了帮助。
在第二种情况下,我们可以阅读规范(8.13.1)
此外,以下两个成员是等价的:
staticopt成员ident.opt ident = expr
staticopt成员ident.opt ident with get()= expr
即。你的x.b实际上是一个每次调用帮助的函数
答案 2 :(得分:0)
方法始终具有隐式this
参数,因此它们始终是函数。在您的情况下,x
是OO代码中的原始参数中不存在的参数。