了解 OCaml 中的命名参数及其范围

Understanding named arguments in OCaml and their scope

我正在阅读 OCaml 源代码,但我对命名参数感到困惑:

 let verify_transport_checksum ~proto ~ipv4_header ~transport_packet =
    (* note: it's not necessary to ensure padding to integral number of 16-bit fields here; ones_complement_list does this for us *)
    let check ~proto ipv4_header len =
      try
        let ph = Marshal.pseudoheader ~src:ipv4_header.src ~dst:ipv4_header.dst ~proto len in
        let calculated_checksum = Tcpip_checksum.ones_complement_list [ph ; transport_packet] in
        0 = compare 0x0000 calculated_checksum
      with
      | Invalid_argument _ -> false
    in
    match proto with
    | `TCP -> (* checksum isn't optional in tcp, but pkt must be long enough *)
      check ipv4_header ~proto (Cstruct.len transport_packet)
    | `UDP ->
      match Udp_wire.get_udp_checksum transport_packet with
      | n when (=) 0 @@ compare n 0x0000 -> true (* no checksum supplied, so the check trivially passes *)
      | _ ->
        check ipv4_header ~proto (Cstruct.len transport_packet)

我看到 verify_transport_checksum 是一个具有以下 3 个名称参数的函数:~proto ~ipv4_header ~transport_packet。然后,在内部,它执行 let check ~proto ipv4_header len =。这是新的 ~proto?

然后它

let ph = Marshal.pseudoheader ~src:ipv4_header.src ~dst:ipv4_header.dst ~proto len in

这是什么~proto?它是 Marshal.pseudoheader 的命名参数吗?如果是这样,为什么它没有价值?

这是在做 label-punning:它从之前获取一些变量绑定,并将其作为同名同值的标记参数传递给另一个函数。

let someArg = "something";;
someFun ~someArg;;
(* is shorthand notation for *)
someFun ~someArg:someArg;;
  • verify_transport_checksum 有标签参数 ~proto.
  • 它用于下面的模式匹配,匹配它,并传递给 check
  • check-definition中的~proto与之前同名,所以可以通过。但是,它隐藏了 ~proto 的先前绑定。如果有人像 check ~proto:"something else here" 那样调用它(在下面的模式匹配中),它将具有不同的值。在您的情况下,因为它被双关,所以它具有与以前完全相同的值。
  • 同样的事情发生在 Marshal.pseudoheader 调用上,来自 check~proto 被传递。