我在Yacfe example中看到了以下函数调用:
Visitor_c.vk_program { Visitor_c.default_visitor_c with
Visitor_c.kexpr = (fun (k, bigf) exp ->
match Ast_c.unwrap_expr exp with
| Binary(e1, Logical (Eq), (((Constant(Int("0")) as _e2),_t),ii)) ->
(match Ast_c.get_onlytype_expr e1 with
| Some (qu, (Pointer _,_ii)) ->
let idzero = Common.tuple_of_list1 ii in
idzero.cocci_tag :=
Ast_cocci.MINUS (Ast_cocci.NoPos, [[null_addon]]), [];
| _ -> k exp
)
| _ -> k exp
);
} ast;
我可以看到一个函数调用,其中记录初始化为第一个参数,ast
作为第二个参数。
我不熟悉的是表单的语法:
{Visitor_c.default_visitor_c with Visitor_c.kexpr = some_value;}
这意味着什么?我知道记录可以像{name=value;name=value;...}
一样初始化,但我不熟悉{X with name=value}
,你能告诉我这意味着什么吗?
我无法在Ocaml Manual中找到除以下内容之外的合法记录值初始化:
6.2.3记录
记录值标记为元组 值。记录的值{ field1 = v1; ...; fieldn = vn} 将值vi与记录相关联 field fieldi,for i = 1 ... n。该 当前的实现支持 最多222个字段的记录 (4194303字段)。
如果您在回答中提及OCaml手册中的相关部分,我将很高兴。
答案 0 :(得分:39)
这有时被称为“记录更新”或“功能更新”或类似的东西。它评估为与X相同类型的新记录,其字段初始化为与X中的字段相同,但在“with”之后列出的字段除外,它们被初始化为给定值。
它对于不可变记录很有用,作为一种方便的方法来获取这样的记录并在其上更改一个或两个东西(在命令式语言中,您通常会改变字段),而不必列出所有字段没有改变。
在OCaml手册section 6.7.3中有描述,向下滚动到“记录”,第二段。
对于熟悉Haskell的人,OCaml语法
{ expr with field1 = expr1 ; ... ; fieldn = exprn }
与Haskell语法相同
expr { field1 = expr1 , ... , fieldn = exprn }
答案 1 :(得分:15)
要更正先前的回复,新记录的类型并不总是与旧记录相同。 例如,你可以有类似的东西:
type 'a t = {
id : int;
value : 'a;
}
let old_t = { id = 3; value = "foo" }
let new_t = { old_t with value = 3 }
因此,old_t
的类型为string t
,而new_t
的类型为int t
。