Ocaml新人,在这里记录一下自己的学习心得,欢迎各路大佬批评指正~
?foo 和 ~foo 在OCaml中分别表示函数的可选和命名参数。这个特性在C衍生的语言中未必有对于的概念,但是Perl,Python和Smalltalk都允许函数忽略某些参数,或者以其他顺序传入参数。
例1:
#let foo ?z:(z=0) x y = (x+y)>z;;
val foo : ?z:int -> int -> int -> bool = <fun>
#foo 1 1 ;;
- : bool = true
#foo (-1) (-1);;
- : bool = false
# foo ~z:(-42) (-1) (-1);;
- : bool = true
例2:
#let fcc x u ?z:(z=0) = (x+y)>z;;
Characters 16-19:
Warnig 16:this optional argument cannot be erased.
cal fcc : int -> int -> ?z:int -> bool = <fun>
#fcc 1 1;;
- : ?z:int -> bool = <fun>
fcc 1 1 ~z:(3);;
- : bool = false
如例1例2,在定义函数的时候,可以用 ?(z=0) 或者 ?z:(z=0) 的形式为参数 z 设定默认值0。用法与c++中函数的默认参数类似,但是规则却是有很大差异:在Ocaml中设置可选参数时,它们不可出现在参数列表的末尾,这可能是函数式编程的特性吧,在下目前还没有理解透,不过在这贴一段国外大神的见解,"Labeled arguments can't appear at the end of the argument list since the function is evaluated as soon as it has everything it needs"。
在例1语句 foo 1 1;; 中,z的值为默认值0,x的值为1,y的值为1,由2>0可知,函数的结果为true。
但是,如果想要在调用函数的时候,手动传入z的值,则需要以 ~z:(42) 的形式“显式”地传入参数 z 的值42,如例1语句 # foo ~z:(-42) (-1) (-1);; ,但是,像 foo 42 1 1 这种写法会出现形如 “Error: The function applied to this argument has type ?z:int -> bool” 的报错。
在例2中,经过实践发现,如果可选参数出现在参数列表末尾,那么我们将无法使用其内设置的默认值,必须手动传入命名参数,函数才会进行运算并返回值。
网友评论