F# 声明变量而不实例化它

F# declare variable without instantiating it

我需要在 F# 中声明一个变量而不实例化它。这在 C# 中很简单,但在 F# 中,我只有 val 关键字,而且它只在 类 范围内有效。有没有一种方法可以为范围目的声明一个变量,但将初始化留到以后?

编辑:回答 Fyodor 的问题:

我想以编程方式遍历包含 C# 序列化文件的文件夹,每个文件都包含一个 A 类或 B 类对象的数组。这些对象中的每一个都有一个时间戳,并且每天有一个 C# 数组文件。假设总共有 20 个文件(10 个 A 文件和 10 个 B 文件),每个文件中有 1000 个 A 对象,或 1000 个 B 对象,每个对象都有一个时间戳,每个文件每天收集 1000 个数据点.

问题是 A 类文件和 B 类文件在一天中的不同时间点开始和停止,所以我不能只选择 Day1A 和 Day1B,合并它们,然后选择 Day2A 和 Day2B,依此类推.我需要经历 Day1A 和 Day1B 直到其中一个完成(比如 A 先完成),然后加载 Day2A 并比较 Day2A 和 Day1B 直到其中一个完成,等等。

为此,我需要枚举每个文件中的 1000 多个对象,以及文件本身。我还需要处理没有类型 A 或类型 B 的奇怪情况(在这种情况下我只是枚举剩余的类型)。

范围开始发挥作用,因为我有两组枚举器遍历两组 while 循环。

F# 中的值是不可变的,因此无法更改值。因此没有办法直接做你想做的事。

相反,人们通常会创建一个“ref cell”——一个变量的容器——它允许更改值的内容。但是您仍然需要初始化单元格。 (有关示例,请参见 link。)

更好的方法是重构代码以避免这种需要(并非总是可行,但 F# 具有足够的语法,这比在 C# 等命令式语言中更可能实现)。

只有极少数情况下您会在 F# 中真正需要它。最有可能的是,您可以找到另一种(更实用和更惯用的)方法来做到这一点。

例如,在 C# 中,如果您想使用 if:

初始化变量,您可能经常需要声明一个变量以达到作用域目的
int some;  
if (Condition()) { some = 1; }
else { Console.WriteLine("yay"); some = 2; }

但在 F# 中不需要这样做,因为 if 是一个表达式:

let some = 
  if Condition() then 1
  else
    Console.WriteLine("yay")
    2

因此,如果您描述您所面临的具体情况,您可能会通过更好地惯用的 F# 解决方案获得更有用的答案。