查看源代码 基本类型
在本节中,我们将深入了解 Elixir 的基本类型:整数、浮点数、布尔值、原子和字符串。其他数据类型,如列表和元组,将在下一节中探讨。
iex> 1 # integer
iex> 0x1F # integer
iex> 1.0 # float
iex> true # boolean
iex> :atom # atom / symbol
iex> "elixir" # string
iex> [1, 2, 3] # list
iex> {1, 2, 3} # tuple
基本算术运算
打开 iex
并输入以下表达式
iex> 1 + 2
3
iex> 5 * 5
25
iex> 10 / 2
5.0
请注意,10 / 2
返回的是浮点数 5.0
,而不是整数 5
。这是预期的结果。在 Elixir 中,运算符 /
始终返回浮点数。如果要进行整数除法或获取除法的余数,可以使用 div
和 rem
函数
iex> div(10, 2)
5
iex> div 10, 2
5
iex> rem 10, 3
1
请注意,Elixir 允许在调用期望一个或多个参数的函数时省略括号。此功能在编写声明和控制流结构时提供更简洁的语法。但是,Elixir 开发人员通常更喜欢使用括号。
Elixir 还支持输入二进制、八进制和十六进制数字的简写形式
iex> 0b1010
10
iex> 0o777
511
iex> 0x1F
31
浮点数需要一个点后跟至少一位数字,并且也支持 e
来表示科学计数法
iex> 1.0
1.0
iex> 1.0e-10
1.0e-10
Elixir 中的浮点数精度为 64 位。
可以使用 round
函数获取最接近给定浮点数的整数,或使用 trunc
函数获取浮点数的整数部分。
iex> round(3.58)
4
iex> trunc(3.58)
3
最后,当我们使用不同的数据类型时,我们将了解 Elixir 提供了几个谓词函数来检查值的类型。例如,可以使用 is_integer
检查值是否为整数
iex> is_integer(1)
true
iex> is_integer(2.0)
false
还可以使用 is_float
或 is_number
分别检查参数是否为浮点数,或同时为整数或浮点数。
识别函数和文档
在我们继续下一个数据类型之前,让我们讨论一下 Elixir 如何识别函数。
Elixir 中的函数由它们的名称和元数标识。函数的元数描述了函数接受的参数数量。从现在开始,我们将使用函数名称及其元数来描述整个文档中的函数。 trunc/1
标识名为 trunc
且接受 1
个参数的函数,而 trunc/2
标识具有相同名称但元数为 2
的另一个(不存在)函数。
我们也可以使用这种语法访问文档。Elixir shell 定义了 h
函数,可以使用它访问任何函数的文档。例如,输入 h trunc/1
将打印 trunc/1
函数的文档
iex> h trunc/1
def trunc()
Returns the integer part of number.
h trunc/1
工作原理是,它是在 Kernel
模块中定义的。Kernel
模块中的所有函数都自动导入到我们的命名空间中。大多数情况下,在查找给定函数的文档时,还会包含模块名称
iex> h Kernel.trunc/1
def trunc()
Returns the integer part of number.
可以使用模块+函数来查找任何内容,包括运算符(尝试 h Kernel.+/2
)。调用不带参数的 h
将显示 IEx.Helpers
的文档,其中定义了 h
和其他功能。
布尔值和 nil
Elixir 支持 true
和 false
作为布尔值
iex> true
true
iex> true == false
false
Elixir 还提供了三个布尔运算符:or/2
、and/2
和 not/1
。这些运算符是严格的,因为它们期望第一个参数是评估为布尔值(true
或 false
)的值
iex> true and true
true
iex> false or is_boolean(true)
true
提供非布尔值将引发异常
iex> 1 and true
** (BadBooleanError) expected a boolean on left-side of "and", got: 1
or
和 and
是短路运算符。它们只在左侧不足以确定结果时才执行右侧
iex> false and raise("This error will never be raised")
false
iex> true or raise("This error will never be raised")
true
Elixir 还提供了 nil
的概念,用于指示值不存在,以及一组也操作 nil
的逻辑运算符:||/2
、&&/2
和 !/1
。对于这些运算符,false
和 nil
被认为是“假值”,所有其他值都被认为是“真值”。
# or
iex> 1 || true
1
iex> false || 11
11
# and
iex> nil && 13
nil
iex> true && 17
17
# not
iex> !true
false
iex> !1
false
iex> !nil
true
原子
原子是一个常量,其值与其名称相同。一些其他语言称其为符号。它们通常用于枚举不同的值,例如
iex> :apple
:apple
iex> :orange
:orange
iex> :watermelon
:watermelon
如果原子的名称相同,则它们相等。
iex> :apple == :apple
true
iex> :apple == :orange
false
它们通常用于表示操作的状态,使用 :ok
和 :error
等值。
布尔值 true
和 false
也是原子
iex> true == :true
true
iex> is_atom(false)
true
iex> is_boolean(:false)
true
Elixir 允许省略原子 false
、true
和 nil
的前导 :
。
字符串
Elixir 中的字符串用双引号分隔,并且以 UTF-8 编码
iex> "hellö"
"hellö"
注意:如果您在 Windows 上运行,则终端可能默认情况下不使用 UTF-8。您可以在进入 IEx 之前运行
chcp 65001
来更改当前会话的编码。
可以使用 <>/2
运算符连接两个字符串
iex> "hello " <> "world!"
"hello world!"
Elixir 还支持字符串插值
iex> string = "world"
iex> "hello #{string}!"
"hello world"
字符串连接需要两侧都为字符串,但插值支持可以转换为字符串的任何数据类型
iex> number = 42
iex> "i am #{number} years old!"
"i am 42 years old!"
字符串中可以包含换行符。可以使用转义序列引入它们
iex> "hello
...> world"
"hello\nworld"
iex> "hello\nworld"
"hello\nworld"
可以使用 IO.puts/1
函数(来自 IO
模块)打印字符串
iex> IO.puts("hello\nworld")
hello
world
:ok
请注意,IO.puts/1
函数在打印后返回原子 :ok
。
Elixir 中的字符串在内部由称为二进制的连续字节序列表示
iex> is_binary("hellö")
true
我们还可以获取字符串中的字节数
iex> byte_size("hellö")
6
请注意,该字符串中的字节数为 6,即使它有 5 个字符。这是因为字符 "ö" 在 UTF-8 中需要 2 个字节来表示。可以使用 String.length/1
函数获取基于字符数量的字符串的实际长度
iex> String.length("hellö")
5
String
模块包含许多在 Unicode 标准中定义的字符串操作函数
iex> String.upcase("hellö")
"HELLÖ"
结构比较
Elixir 还提供了 ==
、!=
、<=
、>=
、<
和 >
作为比较运算符。我们可以比较数字
iex> 1 == 1
true
iex> 1 != 2
true
iex> 1 < 2
true
还可以比较原子、字符串、布尔值等
iex> "foo" == "foo"
true
iex> "foo" == "bar"
false
如果整数和浮点数的值相同,则它们进行相同的比较
iex> 1 == 1.0
true
iex> 1 == 2.0
false
但是,如果您想区分整数和浮点数,可以使用严格比较运算符 ===
和 !==
(这是这两个运算符之间唯一的区别)
iex> 1 === 1.0
false
Elixir 中的比较运算符可以跨任何数据类型进行比较。我们说这些运算符执行 *结构比较*。有关更多信息,请阅读我们有关 结构比较与语义比较 的文档。
Elixir 还提供了用于表达集合的数据类型,例如列表和元组,我们将在下一节中学习。当我们讨论通过进程实现并发和容错时,我们还将讨论端口、pid 和引用,但这将在后面的章节中介绍。让我们继续前进。