为什么当我试图从这个模块返回可变列表的内容时总是得到一个空列表?

时间:2022-05-15 07:21:03

Please, help an F# beginner understand this! I have the following F# code (which I've just created to help me learn, so I realise it's probably terrible):

请帮助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

If I write out the value of account at this stage (after the above code), I see the Account record I expect (Account Two), and if I dump Accounts.accounts, I can see that the mutable list contains both Account records.

如果我在这个阶段(在上面的代码之后)写出account的值,我将看到我期望的account记录(account Two),如果我转储帐户。帐户,我可以看到可变列表包含两个帐户记录。

So why does Account.lst always return an empty list, even though I can see that the list definitely isn't empty?

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

2 个解决方案

#1


7  

Because lst is a value, not a function.

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

In F#, the technical difference between a value and a function is that a function has parameters, and a value does not.

在f#中,值和函数之间的技术差异是函数具有参数,而值不具有参数。

When you declared lst, you didn't give it any parameters, so the compiler understood it as "I want to take the value of accounts at this particular point in time, and refer to that value as lst from now on". So every time you write lst, you're not calling a function, but merely referring to that same empty list that was the value of accounts at initialization time.

当您声明lst时,您没有给它任何参数,因此编译器理解为“我想要在这个特定的时间点上取帐户的值,从现在开始将这个值称为lst”。所以每次你写lst的时候,你不是在调用一个函数,而只是在引用相同的空列表,那是初始化时帐户的值。

To make lst a true function, you need to give it a parameter. And because it doesn't really need any actual data, the natural parameter to give it is the unit value - ().

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

let lst () = accounts

P.S. This whole trickiness ultimately comes from mutating state. Try to avoid it when possible.

附注:这种欺骗最终来自于突变状态。尽量避免。

#2


4  

Because lst is a value not a function. You need to convert it to a function:

因为lst是一个值而不是一个函数。你需要把它转换成一个函数:

let lst () =
    accounts

then you can call it by:

然后你可以这样称呼它:

Accounts.lst()

#1


7  

Because lst is a value, not a function.

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

In F#, the technical difference between a value and a function is that a function has parameters, and a value does not.

在f#中,值和函数之间的技术差异是函数具有参数,而值不具有参数。

When you declared lst, you didn't give it any parameters, so the compiler understood it as "I want to take the value of accounts at this particular point in time, and refer to that value as lst from now on". So every time you write lst, you're not calling a function, but merely referring to that same empty list that was the value of accounts at initialization time.

当您声明lst时,您没有给它任何参数,因此编译器理解为“我想要在这个特定的时间点上取帐户的值,从现在开始将这个值称为lst”。所以每次你写lst的时候,你不是在调用一个函数,而只是在引用相同的空列表,那是初始化时帐户的值。

To make lst a true function, you need to give it a parameter. And because it doesn't really need any actual data, the natural parameter to give it is the unit value - ().

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

let lst () = accounts

P.S. This whole trickiness ultimately comes from mutating state. Try to avoid it when possible.

附注:这种欺骗最终来自于突变状态。尽量避免。

#2


4  

Because lst is a value not a function. You need to convert it to a function:

因为lst是一个值而不是一个函数。你需要把它转换成一个函数:

let lst () =
    accounts

then you can call it by:

然后你可以这样称呼它:

Accounts.lst()