
Elixir 是一门为开发可扩展、可维护的应用程序而设计的一门动态、函数式语言。
Elixir 利用 Erlang 虚拟机,以运行低延迟、分布式和容错系统而著称,同时也成功运用于 Web 开发和嵌入式软件领域。
要了解更多关于 Elixir 的信息,请查看我们的 入门指南,或者继续阅读以了解平台、语言和工具的概述。
平台特性
可扩展性
所有 Elixir 代码运行在轻量级的执行线程(称为进程)中,这些线程通过消息进行隔离和交换信息:
current_process = self()
# 产生一个 Elixir 进程(不是操作系统的进程!)
spawn_link(fn ->
send current_process, {:msg, "hello world"}
end)
# 阻塞,直到收到消息
receive do
{:msg, contents} -> IO.puts contents
end
由于它们的轻量级特性,在同一台机器上 同时 运行数十万个进程并不是稀罕事。隔离允许进程独立进行垃圾收集,减少系统范围的停顿,并尽可能高效地使用所有机器资源(垂直扩展)。
进程还能够与在同一网络中的不同机器上运行的其他进程进行通信。这为分布式提供了基础,允许开发人员跨多个节点协调工作(水平扩展)。
容错
软件在生产环境中运行,存在着的一个不可避免的事实是,事情会出错。当我们把网络、文件系统和其他第三方资源考虑在内时更是如此。
为了应对故障,Elixir 提供了监督者,描述当发生错误时,如何重启部分系统,如何回到一个能保证工作的已知的初始状态:
import Supervisor.Spec
children = [
supervisor(TCP.Pool, []),
worker(TCP.Acceptor, [4040])
]
Supervisor.start_link(children, strategy: :one_for_one)
语言特性
函数式编程
函数式编程倡导一种能帮助开发人员编写简单、快速和可维护代码的编码风格。例如,模式匹配能让开发人员轻松地解构数据并访问其内容:
%User{name: name, age: age} = User.get("John Doe")
name #=> "John Doe"
当与守卫一起使用时,模式匹配使我们能优雅地匹配和声明某些代码执行时所需的具体条件:
def serve_drinks(%User{age: age}) when age >= 21 do
# 提供饮料的代码!
end
serve_drinks User.get("John Doe")
#=> 如果用户小于21岁将会失败
Elixir 很大程度上依赖于这些功能,以确保你的软件在预期的约束下工作。当软件没有按预期工作时,不要担心,还有监督者可以依靠!
可扩展性和 DSL
Elixir 被设计为可扩展的,让开发人员自然地将语言扩展到特定领域,以提高其生产力。
举例说明,我们用一个 名为 ExUnit 的 Elixir 测试框架 编写一个简单的测试用例:
defmodule MathTest do
use ExUnit.Case, async: true
test "can add two numbers" do
assert 1 + 1 == 2
end
end
async: true
选项允许测试并行运行,使用尽可能多的 CPU 核心,而 assert
功能可以内省你的代码,在发生故障时提供出色的报告。这些功能是使用 Elixir 宏构建的,可以添加新的结构,就像它们是语言本身的一部分一样。
工具特性
不断增长的生态系统
Elixir 配备了一整套工具让开发变得更容易。Mix 是一个构建工具,让你可以轻松创建项目、管理任务、运行测试等:
$ mix new my_app
$ cd my_app
$ mix test
.
Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures
Mix 还能够管理依赖关系,并与 Hex 包管理器 完美集成,Hex 提供依赖解析和远程获取包的能力。
交互式开发
像 IEx(Elixir 的交互式 Shell) 这样的工具能够利用语言和平台的诸多方面来提供自动完成、调试工具、代码重新加载以及格式良好的文档:
$ iex
Interactive Elixir - press Ctrl+C to exit (type h() ENTER for help)
iex> c "my_file.ex" # Compiles a file
iex> t Enum # Prints types defined in the module Enum
iex> h IEx.pry # Prints the documentation for IEx pry functionality
iex> i "Hello, World" # Prints information about the given data type