Syntax 为什么可以';我是否在新行上用每个分隔符和字段更新记录?

Syntax 为什么可以';我是否在新行上用每个分隔符和字段更新记录?,syntax,compiler-errors,f#,record,Syntax,Compiler Errors,F#,Record,我正在使用以下记录类型 type MyRecord = { x : int ; y : int ; z : int } let r = { x = 0 ; y = 0 ; z = 0 } 以下汇编 let r' = { r with x = r.x+1; y = r.y+2 } 但是下面 let r' = { r with x = r.x+1 ; y =

我正在使用以下记录类型

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

let r = 
    { x = 0
    ; y = 0
    ; z = 0
    }
以下汇编

let r' =
    { r with x = r.x+1;
             y = r.y+2
    }
但是下面

let r' =
    { r with x = r.x+1
    ;        y = r.y+2
    }
给出编译错误

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.
有人能解释问题出在哪里吗?

在F#中,当记录的字段位于单独的行上时,分号是可选的(事实上完全不需要)。你可以写:

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

let r = 
    { x = 0
      y = 0
      z = 0
    }
那就好了。然后您的
let r'=…
语句可以如下所示:

let r' =
    { r with x = r.x+1
             y = r.y+2
    }
分号仅在将字段放在一行时才是必需的。列表的工作原理与此类似:

let l = [
    1
    2
    3
]
相当于:

let l = [1; 2; 3]
同样,只有在项目位于同一行时才需要分号。如果它们在不同的行上,分号是可选的。

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

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

let r = 
    { x = 0
      y = 0
      z = 0
    }
那就好了。然后您的
let r'=…
语句可以如下所示:

let r' =
    { r with x = r.x+1
             y = r.y+2
    }
分号仅在将字段放在一行时才是必需的。列表的工作原理与此类似:

let l = [
    1
    2
    3
]
相当于:

let l = [1; 2; 3]

同样,只有在项目位于同一行时才需要分号。如果分号位于不同的行上,则分号是可选的。

分号必须至少比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
    }
或者,您可以将表达式替换为等价的表达式,但随后必须明确所有字段(这可能会很乏味):


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

分号必须至少比具有垂直对齐方式的分号缩进得多

// 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
    }
或者,您可以将表达式替换为等价的表达式,但随后必须明确所有字段(这可能会很乏味):


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

谢谢。我不知道它们在列表和记录中是可选的。我还不确定我对依赖空白的感觉如何。我很感激answer@symbiont:如果您不想删除分号,我强烈建议您至少将其置于“标准”位置,即在行尾。这使得它们的功能显而易见,并且不会对可读性造成太大的伤害。同样,省略它们也不是很大的一步。@symbont:我想你应该试试。由于相当完善的类型系统和各种其他编译规则,在实践中,如果编译器没有注意到并阻止您,就很难犯与空白相关的错误。谢谢。我不知道它们在列表和记录中是可选的。我还不确定我对依赖空白的感觉如何。我很感激answer@symbiont:如果您不想删除分号,我强烈建议您至少将其置于“标准”位置,即在行尾。这使得它们的功能显而易见,并且不会对可读性造成太大的伤害。同样,省略它们也不是很大的一步。@symbont:我想你应该试试。由于相当完善的类型系统和各种其他编译规则,在实践中,如果编译器没有注意到并阻止您,就很难犯与空白相关的错误。谢谢。这直接回答了我的问题。我认为如果你不给z赋值,这个替代方案就不起作用了。但这很好know@symbionttrue(编辑后将z放回原处)您必须将所有字段(这就是record copy and update
with
syntax隐藏在幕后)放回原处,谢谢。这直接回答了我的问题。我认为如果你不给z赋值,这个替代方案就不起作用了。但这很好know@symbionttrue(编辑后将z放回原处)您必须将所有字段放回原处(这就是使用语法记录复制和更新