原文:http://2ality.com/2017/12/basic-types-reasonml.html
翻译:ppp
系列文章目录详见: “什么是ReasonML?”
本文中,我们将看看ReasonML对布尔值,整数,浮点数,字符串,字符和单元类型的支持。同时还有一些运算符的用法。 为了进一步学习,我们将使用ReasonML的交互式命令行rtop,它是reason-cli工具包的一部分(安装手册)(译者注:发展太快,现在这个工具很难找到了,官方推荐用在线的运行环境来测试,也很方便地址)。
rtop 的交互如下。
# !true;
- : bool = false
有两点值得注意:
为了得到一个表达式的值,你需要用;
分号来结束它,例中的!true
;。
rtop 通常会打印出运算结果的类型。这一点将会在处理像函数这样更为复杂的类型时,变得非常有用。
ReasonML中的值是静态类型的。 什么是静态类型? 首先,类型就是一组值的集合。 例如,bool是所有布尔值类型的集合: {false, true}的集合。 其次,我们再对代码生命周期的上下文做出以下区分:
因此,静态类型意味着:ReasonML在编译时就知道值的类型。而且在编辑代码时也会知道,这将支持更智能的编辑。
我们已经知道了静态类型的一个好处:在编辑时对类型已知。这能帮助我们检测一些类型错误,同时还有助于做一些代码逻辑上的检查。(译者注:相对于JavaScript的动态类型而言) 为了上述的好处,你应该接受静态“类型”。有两种方式可以帮助你: ReasonML会智能的推断出类型(尽管你可能没有显示的指定)。这种被动式的类型预测让你用起来更方便顺手。 在出现问题时,ReasonML会给出错误的描述信息,甚至可能包含解决问题的提示。也就是说,你可以用试错法来学习类型。
ad-hoc多态听起来很赞,虽然目前不支持,但是ReasonML对它已经有一个简单的定义和计划。
ReasonML目前不支持ad-hoc多态(根据不同的参数类型,实现不同的操作)。另一个函数式编程语言Haskell通过类型类(typeclass)来支持ad-hoc多态。ReasonML最终也可能会通过类似的方式来实现对ad-hoc多态的支持。
不支持ad-hoc多态意味着大多数运算符如 +
(整数的加法),+.
(浮点数加法)和 ++
(字符串连接)只支持单一的数据类型。因此,你需要自己对运算符的数据做适配。不过,如果你忘记了,ReasonML会在编译时提醒你。 这就是静态类型的好处。
在我们继续学习之前,首先让我们来看看如何注释。 ReasonML 只有一种写注释的方法:
/* This is a comment */
可以嵌套注释(C风格的语言通常无法这样使用)这一点是挺方便的。
/* Outer /* inner comment */ comment */
嵌套对于注释代码段非常有用:
/*
foo(); /* foo */
bar(); /* bar */
*/
让我们输入一些布尔表达式:
# true;
- : bool = true
# false;
- : bool = false
# !true;
- : bool = false
# true || false;
- : bool = true
# true && false;
- : bool = false
整形数字表达式如下所示:
# 2 + 1;
- : int = 3
# 7 - 3;
- : int = 4
# 2 * 3;
- : int = 6
# 5 / 3;
- : int = 1
浮点数字表达式如下所示:
# 2.0 +. 1.0;
- : float = 3.
# 2. +. 1.;
- : float = 3.
# 2.25 +. 1.25;
- : float = 3.5
# 7. -. 3.;
- : float = 4.
# 2. *. 3.;
- : float = 6.
# 5. /. 3.;
- : float = 1.66666666666666674
一般字符串使用双引号定义:
# "abc";
- : string = "abc"
# String.length("ü");
- : int = 2
# "abc" ++ "def";
- : string = "abcdef"
# "There are " ++ string_of_int(11 + 5) ++ " books";
- : string = "There are 16 books"
# {| Multi-line
string literal
\ does not escape
|};
- : string = " Multi-line\nstring literal\n\\ does not escape\n"
ReasonML字符串编码为UTF-8,与JavaScript的UTF-16字符串不兼容。ReasonML对Unicode的支持也比JavaScript差。作为一个临时的解决方案,你可以在ReasonML中使用BuckleScript的JavaScript字符串:
Js.log("äöü"); /* garbage */
Js.log({js|äöü|js}); /* äöü */
上面这些字符串通过带有注释的js字面量来定义的,这种用法只有BuckleScript才支持。在原生的ReasonML中,可以得到正常的字符串。
用单引号定义字符。只支持Unicode的前7个字节:
# 'x';
- : char = 'x'
# String.get("abc", 1);
- : char = 'b'
# "abc".[1];
- : char = 'b'
"x".[0] is syntactic sugar for String.get("x", 0).
有时候,你需要一个表示“空”的值。 在ReasonML ()
就是这样一个特殊的值。()
有它自己的类型:unit
单元类型。()
也是这种类型的唯一取值:
# ();
- : unit = ()
就像 null在C语言中一样,()
不属于任何其他类型。
除此之外,单元类型还是没有返回值的函数的默认返回值。 例如:
# print_string;
- : (string) => unit = <fun>
print_string
这个函数只是接收一个字符串并打印,他并没有真正的返回值。
ReasonML’s 的标准库有支持基本类型之间转换的函数:
# string_of_int(123);
- : string = "123"
# string_of_bool(true);
- : string = "true"
所有的类型转换函数都是以下面规则命名。
«outputType»_of_«inputType»
比较运算符,他们是少数几个可以支持多类型的操作符(多态的)。
# 3.0 < 4.0;
- : bool = true
# 3 < 4;
- : bool = true
# 3 <= 4;
- : bool = true
但是你不能在操作符的两边使用不同类型:
# 3.0 < 4;
Error: Expression has type int but expected type float
ReasonML有两个相等运算符。 == 用于判断两个值是否相等,当比较的是引用类型(例如列表)时,比较的是他们的值。
# [1,2,3] == [1,2,3];
- : bool = true
与之不同的是,===比较的是引用本身:
# [1,2,3] === [1,2,3];
- : bool = false
除非你真的是想比较引用本身,不然都应该首选 ==
扫码关注w3ctech微信公众号
共收到0条回复