f# - let vs member in F#,需要澄清一些事情
问题描述
让我们考虑以下代码:
type RulesStore() =
...
static member LoadAsync : Async<RulesStore> =
async {
let! r = Startup.States.GetAsStringAsync("rules") |> Async.AwaitTask
return
if String.IsNullOrEmpty r then
new RulesStore()
else
JsonConvert.DeserializeObject<RulesStore>(r);
}
这是对象内部的静态方法,用于从存储的 json 或新的干净的 json 中获取该对象的实例。
我是否正确地相信,如果我更换:
静态成员 LoadAsync : Async =
和
让 LoadAsync : 异步 =
LoadAsync 将被评估一次,随后的加载将返回相同的结果?如果我错了,这是为什么呢?
解决方案
这有点微妙。首先,您将let
(instance) 与static member
(static) 进行比较,这增加了每个实例发生的事情与所有实例共享的事情之间的明显区别。
更有用的比较是比较正则member
和let
. 微妙的是async
计算本身是延迟的,所以它们只在你执行它们时才运行。
以下是一个示例来说明这一点 - 我在块printf
的定义之前添加了一个async
和一个async
,用于两个let
和member
:
type A() =
let test =
printfn "let: before async"
async {
printfn "let: inside async"
}
member x.Test =
printfn "member: before async"
async {
printfn "member: inside async"
}
member x.RunLet() = test |> Async.RunSynchronously
member x.RunMember() = x.Test |> Async.RunSynchronously
以下是代码的作用:
let a = A()
// prints "let: before async"
a.RunLet()
// prints "let: inside async"
a.RunLet()
// prints "let: inside async"
a.RunMember()
// prints "member: before async"
// and "member: inside async"
a.RunMember()
// prints "member: before async"
// and "member: inside async"
如您所见,每次调用异步计算时,“异步内部”的代码都会重复运行。但是,“异步之前”的代码只运行一次 forlet
并且重复 for member
。
实际上,在异步之前您几乎没有代码,因此这在典型用途中没有太大区别,但有一些区别 - 使用let
,异步计算只构建一次,然后每次重用。
推荐阅读
- python - 在 Hangman 游戏中制作难度功能
- java - 改造在使用动态标题时获取重复标题
- node.js - 终端不显示 yargs 的处理程序值
- html - 将代码移动到 Angular 组件时,猫头鹰轮播不起作用
- python - 如何通过 lambda 函数从 dynamodb 中检索值
- anaconda - 带有 spacy.load('en_core_web_sm') 的 ValueError
- rabbitmq - 当我尝试侦听具有 json 有效负载的队列时,RabbitTemplate 接收和转换方法抛出空指针异常
- django - 获取 2 列的所有值
- php - 如何在laravel中接收两个日期之间的所有天数
- redux-form - redux-form 是否会随着函数工作而改变 prop 参数值?