了解 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
被传递。
我正在阅读 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
被传递。