代码之家  ›  专栏  ›  技术社区  ›  Kris

有没有办法获得可变结构字段的“引用”

  •  0
  • Kris  · 技术社区  · 3 年前

    所以我有一个字段可变的记录类型:

    type mpoint = { mutable x:int ; mutable y: int };;
    let apoint = { x=3 ; y=4};;
    

    我有一个函数,它需要一个'ref',并对它的内容做一些修改。 例如:

    let increment x = x := !x+1;;
    val increment : int ref -> unit = <fun>
    

    有没有办法从可变字段中获取“引用”,以便我可以将其传递给函数。也就是说,我想做如下事情:

    increment apoint.x;; (* increment value of the x field 'in place' *)
    Error: This expression has type int but an expression was expected of type
             int ref
    

    但上述方法不起作用,因为 apoint.x 返回字段的值,而不是其“ref”。如果是Gangang+或C++,我们可以使用 & 运算符以指示我们想要的是地址而不是字段的值: &apoint.x .

    我们如何在Ocaml中做到这一点?

    PS:是的,我知道以这种方式避免使用副作用可能更常见。但我保证,我这样做是有充分理由的,因为它比这个简化/人为的例子更有意义。

    1 回复  |  直到 3 年前
        1
  •  1
  •   Jeffrey Scofield    3 年前

    没有办法完全按照你的要求去做。参考的类型非常具体:

    # let x = ref 3
    val x : int ref = {contents = 3}
    

    引用是具有一个名为 contents .你不能从其他记录的任意可变字段中编造出来。即使您愿意对类型系统撒谎,记录的字段也不会与记录完全相同。

    您可以将字段声明为实际引用:

    type mpoint = { x: int ref; y: int ref; }
    

    那就没问题了, apoint.x 真的是一个参考。但是这种表示方式效率不高,也就是说,它需要更多的内存,并且访问这些值时会有更多的解引用。

    如果API是以命令式风格设计的,那么在OCaml中很难使用。我就是这么看的。另一种说法是点很小。接口应该返回一个新点,而不是修改现有点。