Elixir 入门教程
Elixir 是基于 Erlang VM 的,一种函数式的动态语言,用于构建可伸缩、易维护的应用程序。
Elixir 最广为人知的特点是 运行低延时、分布式、可容错 的系统,且在 Web 开发与嵌入式软件领域广泛的被使用。
本系列教程将带领我们了解更多关于 Elixir 的信息,你可以阅读我们的 Elixir 入门指南 或者继续阅读以获得平台、语言和工具的概述。
Elixir 应用程序特性
可伸缩
Elixir 是基于 Erlang 构建的,因此也继承了 Erlang 的优良基因,比如所有 Elixir 代码运行于相互隔离的轻量级线程中,相互间通过 message 通信:
current_process = self() # 开辟一个新的进程来执行代码 spawn_link(fn -> send current_process, {:msg, "hello world"} end) # 阻塞主线程,防止开辟的新进程还没执行完就退出 # 当收到新进程发送的消息后,输出消息并退出应用程序 receive do {:msg, contents} -> IO.puts contents end
注意: Elixir 或者 Erlang 中的 进程 其实就是其它语言的 线程 概念。千万不要和操作系统的进程概念混淆。
因为 Elixir (Erlang) 进程的轻量特性,在同一台机器上同时运行数十万个进程并不少见。俗称 C100K。
同时,隔离允许独立地对进程进行垃圾收集,减少系统范围内的垃圾回收中断,并尽可能高效地使用所有机器资源(垂直扩展)。
Elixir 进程还可以与同一网络中不同计算机上运行的其它进程通信。这为分布式提供了基础,允许开发人员协调统筹跨多个节点的工作(水平缩放)。
容错性
无论什么软件,运行在什么操作系统上,有一个问题是我们无法避免的: 总是会出错。 即使我们对外宣称 6 个 9 的可靠性 ( 99.9999%)。
如果算上 网络波动、文件系统 IO 瓶颈 以及其它第三方资源不可靠,潜在的问题只会更多。
针对各种失误和问题, Elixir 提供了 supervisor
解决方案,一个用于描述当事情变得扭曲时如何重启我们的系统的某些部分,并返回已知的能保证应用正常运行的初始状态:
children = [ TCP.Pool, {TCP.Acceptor, port: 4040} ] Supervisor.start_link(children, strategy: :one_for_one)
Elixir 语言特性
函数式编程
函数式编程简化了编程范式,提升了编码风格,让我们能够写出简短、快速以及可维护的代码。例如,模式匹配 让我们轻易的就能解构数据并访问所需的内容
%User{name:name, age: age} = User.get("yufei") name #=> "yufei"
甚至当我们想加入 guard 时,模式匹配允许我们优雅的匹配和声明某些代码执行的特定条件:
def drive(%User{age: age}) when age > 16 do # 当年龄大于 16 时的其它逻辑代码 end drive(User.get("yufei") # => 如果年龄小于 16 那么就回失败
从某些方面说,Elixir 强烈依赖那些特性,来确保我们的软件在预期的约束下运行。如果没有,也不用担心,毕竟我们还有最后的杀手锏 supervisors。
可扩展性和特定领域语言 ( DSLs )
Elixir 基于 Erlang,因此也是一种可扩展的语言。我们可以自由的扩展语言到任何领域,以便提高我们的开发速度。
举个例子,我们可以使用 Elixir 的测试框架- ExUnit 来写个简单的测试用例
defmodule MathTest do use ExUnit.Case, async: true test "can add two numbers" do assert 1 + 1 == 2 end end
上面的代码中,async: true
选项允许并行的运行测试,尽可能的使用更多的 CPU 核心,同时 test
断言函数可以内省 ( introspect ) 我们的代码,并提供测试失败下的详细报告。
Elixir 宏使得我们很容易构建出这些特性,并把它们加入到系统中,成为语言本身的一部分存在。
Elixir 工具特性
持续发展壮大的生态系统
Elixir 发布了整套工具来简化开发。 比如 Mix 是一套 build 工具,它让我们简单几步就能创建项目、管理任务、运行测试以及更多:
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 包管理工具 集成,后者提供依赖管理和下载依赖功能。
交互式开发
Elixir 进行交互式开发主要使用 IEx 工具。IEx ( Elixir 的交互式 shell) 提供了语言和平台各方面的特性,如自动完成、调试工具、代码重新载入、良好格式化的文档:
$ iex Interactive Elixir - press Ctrl+C to exit (type h() ENTER for help) iex> h String.trim # Prints the documentation for function iex> i "Hello, World" # Prints information about the given data type iex> break! String.trim/1 # Sets a breakpoint in the String.trim/1 function iex> recompile # Recompiles the current project on the fly
兼容 Erlang
Elixir 运行在 Erlang VM 上,给我们提供了使用 Erlang 生态系统的完整访问能力,Heroku, WhatsApp, Klarna 等等很多公司都在使用它来构建分布式、高容错的应用程序。
Elixir 程序员可以调用 Erlang 函数并且没有任何运行时开销:
iex> :crypto.hash(:md5, "Using crypto from Erlang OTP") <<192, 223, 75, 115, ...>>