gpt4 book ai didi

f# - 在 F# 属性中使用 lazy 是否会阻止在不应该计算代码时计算代码?

转载 作者:行者123 更新时间:2023-12-05 09:04:20 24 4
gpt4 key购买 nike

我有一个共同的模式:

type something =
{
... a lot of stuff
}

member this.Description =
"a string description of the content, can be long tables, etc"

我希望 Description 属性仅在我需要时才被评估;在许多情况下,它不会被使用,但它可以(主要是根据用户的请求)。

我注意到这段代码会导致 Description 在不需要时被求值。所以我将代码移动到一个函数:Describe() 并解决了问题。

在进行重构时,我正在重新审视这一点。虽然它在实践中不会让任何事情变得更好,但我想知道是否有类似的东西:

member this.Describe =
(lazy "the long to build text output").Value

能解决问题吗?因为将创建惰性对象,但不会查询值本身。

这样能可靠地工作吗?

最佳答案

您声明属性的方式本质上是一个函数。它没有任何参数,但每次有人试图读取它的值时都会执行其主体中的代码。这就是属性在 .NET 中的一般工作方式。

这意味着无论您将其放入其中,仍会在每次访问时执行。试试这个:

type T() =
member this.Y =
printfn "Accessing value of Y"
42

let t = T()
let a = t.Y
let b = t.Y
let c = t.Y

您应该会看到“Accessing value of Y”打印了三次。

如果你把整个东西包装在 lazy 中也没关系:你仍然在每次访问该属性时构建一个全新的 Lazy 对象,然后立即读取其值,从而导致其主体进行评估。

如果您真的想 (1) 延迟评估直到需要和/或 (2) 缓存评估值,您应该在属性主体外部创建 Lazy 对象,然后让属性读取它的值,以便在每次属性访问时读取相同的 Lazy 对象:

type T() =
let x = lazy (
printfn "Calculating value of X"
"expensive computation"
)

member this.X = x.Value

let t = T()
let a = t.X
let b = t.X
let c = t.X

这只会打印一次“Calculating value of X”。

关于f# - 在 F# 属性中使用 lazy 是否会阻止在不应该计算代码时计算代码?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68819990/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com