Что точка (.) Делает в методе F # - PullRequest
4 голосов
/ 04 апреля 2011

Извините за расплывчатое описание, не могу найти лучшего способа изложить его.

Я начинаю с F # и, как и многие другие, я перевожу свои решенные проблемы Эйлера на 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.Если я уберу его, жалоба компилятора скажет:

Этот элемент экземпляра нуждается в параметре для представления вызываемого объекта.Сделайте член статичным или используйте член нотации x.Member (args)

Извините, если это тривиально, и, возможно, я не использую правильную формулировку, но не смог получить ответ с Google.

Спасибо

Ответы [ 2 ]

4 голосов
/ 04 апреля 2011

Если вы знакомы с 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 bound в модулях, без необходимости использования TestFixture s и т.п., что намного лучше подходит для 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, а скорее как функции внутри модуля.

2 голосов
/ 04 апреля 2011

Это по-прежнему класс, поэтому каждый член должен быть статическим или иметь определение "this".

В вашем тесте "test" - это "this" для члена.

Обычно класс выглядел бы так:

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

С периодом использовалось слово «тест», без которого он не знал, какой это член.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...