为什么我不能用新行上的每个分隔符和字段更新记录?

sym*_*ont 1 syntax f# compiler-errors record

我正在使用以下记录类型

type MyRecord =
    { x : int
    ; y : int
    ; z : int
    }

let r = 
    { x = 0
    ; y = 0
    ; z = 0
    }
Run Code Online (Sandbox Code Playgroud)

以下编译

let r' =
    { r with x = r.x+1;
             y = r.y+2
    }
Run Code Online (Sandbox Code Playgroud)

但以下

let r' =
    { r with x = r.x+1
    ;        y = r.y+2
    }
Run Code Online (Sandbox Code Playgroud)

给出编译错误

error FS0010: Unexpected symbol ';' in expression. Expected '}' or other token.
error FS0604: Unmatched '{'
error FS0010: Unexpected symbol '}' in binding. Expected incomplete structured construct at or before this point or other token.
Run Code Online (Sandbox Code Playgroud)

任何人都可以解释问题是什么?

rmu*_*unn 5

在F#中,当记录的字段位于不同的行上时,分号是可选的(事实上,完全没有必要).你可以写:

type MyRecord =
    { x : int
      y : int
      z : int
    }

let r = 
    { x = 0
      y = 0
      z = 0
    }
Run Code Online (Sandbox Code Playgroud)

这会编译得很好.然后你的let r' = ...陈述看起来像:

let r' =
    { r with x = r.x+1
             y = r.y+2
    }
Run Code Online (Sandbox Code Playgroud)

只有在将字段放在一行上时才需要分号.列表的工作方式类似:

let l = [
    1
    2
    3
]
Run Code Online (Sandbox Code Playgroud)

相当于:

let l = [1; 2; 3]
Run Code Online (Sandbox Code Playgroud)

同样,只有当项目在同一行时才需要分号.如果它们在不同的行上,则分号是可选的.


Seh*_*cht 5

分号必须至少比with更加缩进

// as is this code won't compile (multiple definition of y)
let r' =
    { r with x = r.x + 1
           ; y = r.y + 2  // correct
         ;   y = r.y + 2  // correct
        ;    y = r.y + 2  // error
    }
Run Code Online (Sandbox Code Playgroud)

或者你可以用它的等价替换with表达式,但是你必须明确所有的字段(这可能是乏味的):

let r' = r in // not sure where you would put that bit
    { x = r.x + 1
    ; y = r.y + 2
    ; z = r.z
    }
Run Code Online (Sandbox Code Playgroud)

但是,正如rmunn所说,所有这些分号都是可选的,具有垂直对齐