2013-05-10 54 views
2

我正在使用FsUnit在F#中編寫一些單元測試,並且我注意到屬性中有一些奇怪的行爲,並讓類型成員中的語句讓人想知道是否有人可以解釋它?類型成員中的屬性和讓語句

如果我寫這樣一個測試:

[<Fact>] member test. 
    ``Test that something works correctly``() = 

    let x = 1 

    x + 2 |> should equal 3 

我會得到一個錯誤在Visual Studio 2012年的 'X + 2' 線的第一個字符說:

Unexpected keyword 'let' or 'use' in expression. Expected 'in' or other token.

使用「讓......在」解決這個錯誤得到,但如果你想使用一個以上的讓它得到快速凌亂:

[<Fact>] member test. 
    ``Test that something works correctly``() = 
    let x = 1 
    in x + 2 |> should equal 3 

我最終發現,具有一個單獨的行屬性也得到周圍的錯誤:

[<Fact>] 
member test. 
    ``Test that something works correctly``() = 

    let x = 1 

    x + 2 |> should equal 3 

任何人都可以提供關於爲什麼第一代碼片段會導致錯誤,但其他兩個沒有任何見解?

+6

它看起來像一個縮進問題。 – Gabe 2013-05-10 14:23:36

回答

5

在第一個代碼段中,實際上有兩個縮進錯誤。第一個問題是''Test that something works correctly''應該在member關鍵字後縮進。第二個是函數的主體應該在所有行成員定義之後縮進。

如果解決的第一個錯誤:

[<Fact>] member test. 
      ``Test that something works correctly``() = 
    let x = 1 
    x + 2 |> should equal 3 

,編譯器會發出「可能不正確縮進」的警告,您可以通過進一步縮進的函數體修復:

[<Fact>] member test. 
      ``Test that something works correctly``() = 
      let x = 1 
      x + 2 |> should equal 3 

在第二個片段中,使用in關鍵字觸發器verbose syntax,其中縮進無關緊要。在最後一個例子中,member碰巧有最低的縮進;你偶然有正確的縮進。

也就是說,您應該避免將成員定義分解爲多行。在大多數情況下,您可以使用let綁定而不是更詳細的member綁定。

[<Fact>] 
let ``Test that something works correctly``() = 
    let x = 1 
    x + 2 |> should equal 3 
+4

或者,'let [] name = ...' – 2013-05-10 14:54:47

+0

@pad有趣的是多行元素中的縮進;如果我在下一行保留名稱,但將其縮進超出它的成員關鍵字的作用。 – 2013-05-10 15:25:14

+0

@RamonSnir我不知道你可以在let後應用屬性,非常方便。 – 2013-05-10 15:26:58

3

正如在評論中提到,你可以let後或member後放的屬性。通過這種方式,你可以把註釋和成員定義上一行:

let [<Fact>] ``Test that something works correctly``() = 
    let x = 1 
    x + 2 |> should equal 3 

還有當你真正需要使用此語法的情況下。如果你有多個相互遞歸功能(即可以相互調用),那麼你需要使用let rec ... and定義他們,在這種情況下,你必須把屬性and後:

let rec [<Test>] a() = 10 
and [<Test>] b() = 10 

但下面不會是有效語法:

[<Test>] 
let rec a() = 10 
[<Test>] 
and b() = 10