Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
什么是惯用的F#等价于声明一个变量以供以后在C中使用#_F#_Immutability - Fatal编程技术网

什么是惯用的F#等价于声明一个变量以供以后在C中使用#

什么是惯用的F#等价于声明一个变量以供以后在C中使用#,f#,immutability,F#,Immutability,在C#中,我可以声明未初始化的变量,然后在类的各种方法中分配给这些变量。例如,在NUnit测试中,我可以声明一个类型化变量,该变量仅在setup方法中初始化,然后在各种测试中重复使用 private MyTestClass sut; public Setup() { sut = new MyTestClass(); etc. } public FirstTest() { sut.DoSomeWork(1); } public SecondTest() {

在C#中,我可以声明未初始化的变量,然后在类的各种方法中分配给这些变量。例如,在NUnit测试中,我可以声明一个类型化变量,该变量仅在setup方法中初始化,然后在各种测试中重复使用

private MyTestClass sut;

public Setup()
{
    sut = new MyTestClass();
    etc.
}

public FirstTest()
{
    sut.DoSomeWork(1); 
}

public SecondTest()
{
    sut.DoSomeWork(2);
}
我想用F#做同样的事情。然而,根据和其他人的观点,未分配的“变量”在F#中并不是已经完成的事情

在我的F#测试中,测试没有任何类型,只是在一个模块中,因此
[]val
无法工作。 使用
mutable
感觉不太好,因为这似乎是F#编码器的最后选择


既然idomatic F#不应该要求未赋值,那么解决这个问题的“正确”方法是什么?

您可以使用函数和值。不需要声明未分配的变量

let makeTestClass() =
    MyTestClass()
    // etc.

let ``First test``() =
    let sut = makeTestClass()
    sut.DoSomeWork()

let ``Second test``() =
    let sut = makeTestClass()
    sut.DoSomeWork()

您可以使用
lazy

let sut = lazy (new MyTestClass())
lazy
延迟表达式的执行,直到需要结果为止。对延迟值的后续请求不需要重新计算,它只返回上次存储的结果

然后你可以做:

let ``First test``() =
    sut.Force().DoSomeWork(1)

let ``Second test``() =
    sut.Force().DoSomeWork(2)

如果初始化很昂贵并且您不想重复,这可能是合适的。

让sut=new MyTestClass()有什么问题吗?为什么需要这些变量?有没有理由不能在使用它们的地方声明它们?在你的C#示例中,这两个测试不能并行执行,你是自食其果。当然,我不应该每次在使用它的地方都声明变量。如果每个测试都需要该类的一个相同初始化的实例,那么该初始化应该在设置中。如果您有大量的测试,并且每个测试都需要对各种helper类进行复杂的初始化,您会怎么做。你不想在每次测试中都这样做。您可以将它粘贴到一个助手中,该助手将在每次测试之前运行以进行初始化,即设置方法。我是否误解了什么?@s952163,如果我使用
let sut=new MyTestClass()
,则该值将变为不可变的,并且在我的设置函数的上下文中是本地的。然而,我在F#测试中真正想要的是以这样一种方式声明它,即我可以在模块中的任何后续测试中访问它。我可以看出,您可以通过在
类型中声明成员来实现这一点,但我的印象是,在F#中,我可以让测试“自由浮动”,也就是说,在类之外的模块中?我对这个功能性的东西很陌生,所以如果我用错误的方式思考问题,请纠正。尽管忘记
设置
功能,你不需要它。你可以直接将sut=new MyTestClass()
放在模块中。我看不出这与设置方法的上下文有什么关系?这样做会在每个测试中交换声明和初始化(如上面Fyodor所建议的),以调用方法返回测试类。如果这是在F#中做事情的标准方法,那么我会这么做,但我不能不认为我错过了一个技巧。我是说不要使用设置方法。这是惯用的F#。它很简单,允许测试并行运行。