我已经定义了类似的类型:
type s_program =
{ globals : s_var list;
main: s_block; }
and s_var =
{ s_var_name: string;
s_var_type: s_type;
s_var_uniqueId: s_uniqueId }
and s_uniqueId = int
在我的计划中,我有一个变量p: s_program
,但我需要更改s_var_uniqueId
的每个元素的p.globals
,例如,添加1
到s_var_uniqueId
每p
。我有一些问题:
1)我可以直接修改p':s_program
中的相关值,还是必须为新let p' =
{ p with
globals = List.map (fun var -> { var with s_var_uniqueId = var.s_var_uniqueId + 1 }) p.globals
2)我可以这样写:
with
非常感谢。
修改1:按建议更正{{1}}部分
答案 0 :(得分:4)
首先,您可能需要阅读this section on record in OCaml和this chapter on modifiable data structures。如上所述,您将看到记录不可变。其次,你需要考虑你真正想要的东西:可变记录,带有可变字段的记录或带有可变字段的可变记录。例如,假设我们有复数的记录(这是ref 1中的相同示例)。
type complex = { re:float; im:float } ;;
如果您宣布类似
的内容let c = {re=2.;im=3.} ;;
然后您既不能更改c
也不能更改re
(或im
)。确实c := {re=4.;im=6.} ;;
或c.re := 4.;;
都会因错误而失败。要获得可变记录,您只需使用c
的引用。
let c = ref {re=2.;im=3.} ;;
然后,您可以使用c
更改c := {re=4.;im=6.} ;;
。但我认为你想拥有可变领域!然后你必须确定哪些字段是可变的。假设您希望所有字段都是可变的,您可以编写
type complex = { re:float ref; im:float ref }
let make_complex r i = { re = ref r ; im = ref i }
let c = make_complex 3. 4.
;;
然后使用
更改字段c.re := 6. ; c.im := 7. ;;
使用float -> float -> ()
let change_re c r = c.re := r ;;
let change_im c i = c.im := i ;;
let change_complex c r i = change_re c r ; change_im c i ;;
但是,我建议你真的考虑在你的代码中加入这样的命令功能。这可能是完全破坏其可读性的简单方法。
答案 1 :(得分:3)
1)这取决于您是否要将Ocaml用作命令式或函数式编程语言:)。如果是前者,则可以使记录的两个字段都可变(通过在字段名称之前添加可变关键字),然后在适当的位置更改它们。但是我强烈建议不要这样做并且:
2)使用你的第二种方法,看起来非常好(除了你似乎缺少{...}
进行第二次修改。