function - 是否在每个函数调用上评估可选参数的默认值?
问题描述
OCaml 规范记录了对可选参数的默认值的使用,但没有指定如果默认值是例如每次可以返回不同值的函数会发生什么。
从一些测试来看,如果没有传入参数,似乎每次都会评估该值;例如
let x = ref 0;;
let incr x =
x := !x + 1;
!x
;;
let test ?(a = incr x) () = a;;
调用test ()
导致 1、2、3,...,每次递增,但调用test ~a:123 ()
不会递增 ref。
看起来像是跑步的行为,test ()
或者test ~a ()
大致类似于
let test ?a () =
let a =
match a with
| None -> incr x
| Some a -> a
in
body_of_test ~a ()
;;
这是建模的正确方法吗?而且,这种行为是否记录在某处?
解决方案
这确实是预期的行为。从文档中查看(强调我的):
形式的函数
fun ? lab :( pattern = expr0 ) -> expr
等价于fun ? lab : ident -> let pattern = match ident with Some ident -> ident | None -> expr0 in expr
where
ident
是一个新变量,除了在expr0
评估时未指定。
尽管对增量的评估按照您的想法进行,但在函数应用程序中“隐藏”效果是非常不明智的。值得注意的是,以下代码可能返回true
或false
不保证另一个版本的编译器会给出相同的行为。
let test2 ?(a = incr x) ?(b = incr x) () = a < b
if test2 () then ...
推荐阅读
- javascript - 基于多个条件的 Javascript 数组排序(一次迭代)
- c++ - 使用 fdopen 的正确方法
- vb.net - 当输入的大小可能发生变化时如何修改文本文件的一部分
- blueprism - 无法加载无法识别的应用程序类型浏览器启动
- tcp - Sim7080G 模块在使用 GNSS 时无法通过 TCP 发送数据
- windows - windows/delphi 中的 Alpha 3 语言扩展从哪里获取?
- swift - 如何快速删除滚动视图侧边栏
- c - 哪种方法更适合在 C 中的循环中递增和遍历
- java - 调用 CRUD 存储库时 Spring AutoWire 不起作用
- python - 将 python 脚本与 HTML 输入页面链接