f# - 为什么当我尝试从此模块返回可变列表的内容时,总是得到一个空列表?

标签 f#

请帮助 F# 初学者理解这一点!我有以下 F# 代码(我刚刚创建它来帮助我学习,所以我意识到它可能很糟糕):

type Account = {
    ID: Guid
    Name: string
};

module Accounts =
    let mutable accounts:Account list = []

    // Why does this always return empty?
    let lst =
        accounts

    let load id =
        accounts |> List.find(fun a-> a.ID = id)

    let save account =
        accounts <- account::accounts

Accounts.save { ID = Guid.NewGuid(); Name = "Account One"}

let id = Guid.NewGuid()

Accounts.save { ID = id; Name = "Account Two"}

let account = Accounts.load id

如果我在这个阶段写出 account 的值(在上面的代码之后),我会看到我期望的 Account 记录(账户二),如果我dump Accounts.accounts,我可以看到可变列表包含两个 Account 记录。

那么为什么 Account.lst 总是返回一个空列表,即使我可以看到该列表肯定不是空的?

最佳答案

因为 lst 是一个值,而不是一个函数。

在 F# 中,值和函数之间的技术区别在于函数有参数,而值没有。

当您声明 lst 时,您没有给它任何参数,因此编译器将其理解为“我想在以下位置获取 accounts 的值这个特定的时间点,并从现在起将该值称为 lst”。所以每次你写 lst 时,你都不是在调用一个函数,而只是引用同一个空列表,它是初始化时 accounts 的值。

要使 lst 成为一个真正的函数,您需要给它一个参数。因为它实际上并不需要任何实际数据,所以给它的自然参数是 unit 值 - ()

let lst () = accounts

附言这整个棘手问题最终来自变异状态。尽可能避免它。

关于f# - 为什么当我尝试从此模块返回可变列表的内容时,总是得到一个空列表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38979714/

相关文章:

未发现 F# XUnit 测试

f# - 在 Mono 下 fsharp 编译失败并出现 NuGet 错误

f# - 在 F# 中计算列表中未更改的元素数

f# - typeof <'x' > 结果为 "Type inference caused the type variable x to escape its scope"

f# - 在 Mono 上的 F# 中签名 dll 的问题

用于实现 'virtual' 属性(实现接口(interface))的 F# 语法

f# - 以下 FsCheck 测试有什么问题

function - F# 函数不允许我改变可变值

error-handling - 我想编写一个将 float 重写为连续分数的函数

f# - 将字符列表(或数组)转换为字符串