句点(。)在F#方法中的作用

时间:2011-04-04 02:21:16

标签: f#

对于模糊的描述感到抱歉,找不到更好的方法来说明问题。

我开始使用F#和许多其他人一样,我正在将解决的Euler问题转换为F#。我喜欢使用测试运行我的代码,也喜欢FsUnit风格。在给定示例的帮助下,我做到了这一点:

open System
open NUnit.Framework
open FsUnit

type EulerProblem() =
    member this.problem1 = Seq.init 999 (fun n -> n + 1)
                             |> Seq.filter (fun n -> n % 3 = 0 || n % 5 = 0)
                             |> Seq.sum

[<TestFixture>]
type ``Given an Euler problem`` () =
    let euler = new EulerProblem()

    [<Test>] member test.
        ``when I try to solve #1 should return [the magic number]`` ()=           
            euler.problem1 |> should equal [the magic number]

这有效,但我无法理解test方法之后的时间段。如果我把它拿走,编译器投诉说:

  

此实例成员需要一个参数来表示要调用的对象。使成员静态或使用符号'member x.Member(args)

很抱歉,如果这是微不足道的,也许我没有使用正确的措辞,但无法通过谷歌得到答案。

由于

2 个答案:

答案 0 :(得分:4)

如果您熟悉C#,Java或C ++,则可以使用实例成员中的this保留字来引用类实例。在F#中,您必须为每个成员定义的类实例显式命名,在FsUnit示例中,给出的名称仅为test,但实际上并未使用。您可以将测试方法编写为

[<Test>] member this.
    ``when I try to solve #1 should return [the magic number]`` ()=           
        euler.problem1 |> should equal [the magic number]

但是请注意,现在,xUnit.net和NUnit都允许分别应用他们的[<Fact>][<Test>]属性来标记模块内的let绑定函数的测试,而不需要TestFixture和这样,更适合F#。所以,例如,你给出的测试可以并且在我看来应该写成:

module EulerProblemTests () =
    [<Test>]
    let ``when I try to solve #1 should return [the magic number]`` () =           
        let euler = new EulerProblem()  
        euler.problem1 |> should equal [the magic number]

此外,您可能不希望将问题解决方案创建为type EulerProblem的成员,而不是模块中的函数。

答案 1 :(得分:2)

它仍然是一个类,因此每个成员必须是静态的,或者定义了“this”。

在你的测试中,“test”是会员的“this”。

通常这个课程看起来像这样:

type ClassName() =
    member thisname.MethodName() =
        DoSomeStuff |> DoMoreStuff

对于句号,正在使用“测试”一词,没有它就不知道它是什么类型的成员。