Elixir学习笔记——基本类型

在本章中,我们将学习更多关于 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 之所以有效,是因为它是在内核模块中定义的。内核模块中的所有函数都会自动导入到我们的命名空间中。在查找给定函数的文档时,您通常还会包含模块名称:

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 模块中的 IO.puts/1 函数打印字符串:

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 和引用,但这些将在后面的章节中讨论。让我们继续前进。

相关推荐
m0_7482500316 分钟前
【STM32】F103ZET6开发板----笔记01
笔记·stm32·嵌入式硬件
1101 110119 分钟前
STM32-笔记16-定时器中断点灯
笔记·stm32·单片机
sin220119 分钟前
springboot测试类里注入不成功且运行报错
spring boot·后端·sqlserver
旺旺大力包1 小时前
【 Git 】git 的安装和使用
前端·笔记·git
PP东1 小时前
ES学习class类用法(十一)
javascript·学习
kirito学长-Java1 小时前
springboot/ssm网上宠物店系统Java代码编写web宠物用品商城项目
java·spring boot·后端
海绵波波1072 小时前
flask后端开发(9):ORM模型外键+迁移ORM模型
后端·python·flask
余生H2 小时前
前端Python应用指南(二)深入Flask:理解Flask的应用结构与模块化设计
前端·后端·python·flask·全栈