F# 为什么闭包不能在成员函数上正常工作?
如果我正常操作,它将按预期工作并缓存结果:F# 为什么闭包不能在成员函数上正常工作?,f#,closures,F#,Closures,如果我正常操作,它将按预期工作并缓存结果: let help = let tmp = printfn "oh no" 1+1 fun () -> tmp help () help () >oh no 但是,如果我将其作为成员函数,它将不再工作: type test = { a: float } member
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
这才是真正的区别-
let help = let tmp = printfn "oh no"
1+1
fun () -> tmp
printfn "here"
help ()
help ()
这张照片
here
oh no
所以实际上,帮助在被调用之前就已经形成了
在第二种情况下,我们可以阅读规范8.13.1
此外,以下两个成员是等效的:
staticopt成员标识。opt标识=expr
staticopt成员标识。get=expr的opt标识
也就是说,您的x.b实际上是一个每次调用帮助的函数这是真正的区别-
let help = let tmp = printfn "oh no"
1+1
fun () -> tmp
printfn "here"
help ()
help ()
这张照片
here
oh no
所以实际上,帮助在被调用之前就已经形成了
在第二种情况下,我们可以阅读规范8.13.1
此外,以下两个成员是等效的:
staticopt成员标识。opt标识=expr
staticopt成员标识。get=expr的opt标识
也就是说,你的x.b实际上是一个每次调用帮助的函数,正如@John所说,根据,你的帮助属性相当于
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
正如@John所说,根据,您的帮助属性相当于
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
方法总是有一个隐式的this参数,所以它们总是函数。在您的例子中,x是OO代码中的一个参数,它在原始代码中不存在。方法总是有一个隐式的this参数,因此它们总是函数。在您的例子中,x是OO代码中的一个参数,在原始代码中不存在。一个值得指出的小错误,它应该在这里而不是这里打印哦不,没有一个值得指出的小错误,它应该在这里而不是这里打印哦不