在本章中,我们将学习更多关于 Elixir 基本类型:整数、浮点数、布尔值、原子和字符串。其他数据类型,如列表和元组,将在下一章中探讨。
基本算术
打开 iex 并输入以下表达式:
请注意,10 / 2 返回的是浮点数 5.0,而不是整数 5。这是意料之中的。在 Elixir 中,运算符 / 始终返回浮点数。如果要执行整数除法或获取除法余数,可以调用 div 和 rem 函数:
请注意,Elixir 允许您在调用需要一个或多个参数的函数时删除括号。此功能在编写声明和控制流构造时提供了更清晰的语法。但是,Elixir 开发人员通常更喜欢使用括号。
Elixir 还支持输入二进制、八进制和十六进制数字的快捷方式:
浮点数需要一个点,后面跟着至少一个数字,并且还支持科学计数法中的 e:
Elixir 中的浮点数具有 64 位精度。
您可以调用 round 函数来获取最接近给定浮点数的整数,或者调用 trunc 函数来获取浮点数的整数部分。
最后,我们使用不同的数据类型,我们将学习 Elixir 提供的几个谓词函数来检查值的类型。例如,is_integer 可用于检查值是否为整数:
您还可以使用 is_float 或 is_number 分别检查参数是否是浮点数,或者是整数或浮点数。
识别函数和文档
在我们继续讨论下一个数据类型之前,让我们先讨论一下 Elixir 如何识别函数。
Elixir 中的函数通过其名称和参数数量来识别。函数的参数数量描述了函数所采用的参数数量。从现在开始,我们将在整个文档中使用函数名称及其参数数量来描述函数。trunc/1 标识名为 trunc 并采用 1 个参数的函数,而 trunc/2 标识另一个(不存在的)函数,该函数具有相同的名称,但参数数量为 2。
我们还可以使用此语法来访问文档。Elixir shell 定义了 h 函数,您可以使用它来访问任何函数的文档。例如,输入 h trunc/1 将打印 trunc/1 函数的文档:
h trunc/1 之所以有效,是因为它是在内核模块中定义的。内核模块中的所有函数都会自动导入到我们的命名空间中。在查找给定函数的文档时,您通常还会包含模块名称:
您可以使用模块+函数来查找任何内容,包括运算符(尝试 h Kernel.+/2)。调用不带参数的 h 会显示 IEx.Helpers 的文档,其中定义了 h 和其他功能。
布尔值和 nil
Elixir 支持 true 和 false 作为布尔值:
Elixir 还提供了三个布尔运算符:or/2、and/2 和 not/1。这些运算符是严格的,因为它们期望将计算结果为布尔值(true 或 false)的东西作为其第一个参数:
提供非布尔值将引发异常:
or 和 and 是短路运算符。如果左侧不足以确定结果,则仅执行右侧:
Elixir 还提供了 nil 的概念,以表示值的缺失,以及一组也操作 nil 的逻辑运算符:||/2、&&/2 和 !/1。对于这些运算符,false 和 nil 被视为“falsy”,所有其他值被视为“truthy”:
原子
原子是一个常量,其值是其自身名称。其他一些语言称之为符号。它们通常用于枚举不同的值,例如:
如果原子的名称相等,则它们相等。
它们通常用于表达操作的状态,通过使用诸如 :ok 和 :error 之类的值。
布尔值 true 和 false 也是原子:
Elixir 允许您跳过原子 false、true 和 nil 的前导 :。
字符串
Elixir 中的字符串由双引号分隔,并且采用 UTF-8 编码:
注意:如果您在 Windows 上运行,则您的终端可能默认不使用 UTF-8。您可以在进入 IEx 之前运行 chcp 65001 来更改当前会话的编码。
您可以使用 <>/2 运算符连接两个字符串:
Elixir 还支持字符串插值:
字符串连接要求双方都是字符串,但插值支持任何可以转换为字符串的数据类型:
字符串中可以有换行符。您可以使用转义序列引入它们:
您可以使用 IO 模块中的 IO.puts/1 函数打印字符串:
请注意,IO.puts/1 函数在打印后返回原子 :ok。
Elixir 中的字符串在内部由连续的字节序列(称为二进制)表示:
我们还可以获取字符串中的字节数:
请注意,该字符串中的字节数为 6,即使它有 5 个字素。这是因为字素“ö”在 UTF-8 中需要 2 个字节来表示。我们可以使用 String.length/1 函数根据字素数量获取字符串的实际长度:
String 模块包含一组对 Unicode 标准中定义的字符串进行操作的函数:
结构比较
Elixir 还提供 ==、!=、<=、>=、< 和 > 作为比较运算符。我们可以比较数字:
但也可以比较原子、字符串、布尔值等:
如果整数和浮点数具有相同的值,则它们的比较结果相同:
但是,如果您想区分整数和浮点数(这是这些运算符之间的唯一区别),则可以使用严格比较运算符 === 和 !==:
Elixir 中的比较运算符可以跨任何数据类型进行比较。我们说这些运算符执行结构比较。有关更多信息,您可以阅读我们关于结构与语义比较的文档。
Elixir 还提供了用于表达集合的数据类型,例如列表和元组,我们将在下文中学习。当我们讨论通过进程实现的并发性和容错性时,我们还将讨论端口、pid 和引用,但这些将在后面的章节中讨论。让我们继续前进。