概述

Elixir 是一种基于 Erlang 虚拟机的函数式,面向并行的通用语言, 它是一门通用语言,所以不仅可以用在擅长的高可用,高并发场景下,也可以用在 web 开发等场景下。 Erlang 诞生于 1986 年,爱立信。

有了 Erlang,为什么还要 Elixir? Erlang 毕竟诞生的早,虽然有很多优秀的特性,但是语法非常晦涩难懂,甚至没有支持 String Elixir 只是 Erlang 很简单的封装,不仅保留了 Erlang 所有的优秀特性,还提供了类似 Ruby 那样高效的语法。

和 Erlang 相比,Elixir 的语法有 2 个明显的优势

  • macro: 可以简化很多的代码
  • pipeline: |> 可以省却很多临时变量的定义

环境搭建

官方安装文档:https://elixir-lang.org/install.html 建议在 Unix-like 的系统下通过编译源码的方式安装,能够及时体验最新的特性

安装 Elixir 之前要先安装 Erlang

语言基础

在 Elixir 中,任何东西都可以理解为 *表达式+返回值*。 Elixir 中,任何数据不可改变,变量的赋值本质是把变量指向了其他的内存地址,不改变变量原来内存地址中的内容, 所以,等于(=)在 Elixir 中其实是 绑定(binding) 的意思,把右边的值绑定到左边的变量上,并返回右边的值

类型

Elixir 中的类型主要有以下几类:

Number

Elixir 中整数和小数统称为数值类型,整数的除法和求余用 div 和 rem 宏来实现

Atom

原子存在原子表中,不会被 GC 自动回收 true/false 在 Elixir 中是原子 :true/:false nil 在 Elixir 中是原子 :nil

Tuple

元素个数是固定的,适用于小的集合 通过 put_elem 修改 tuple 之后,其实返回的是一个新的 tuple,原来的 tuple 并没有被修改

List

list 可以表示为 [head|tail] 在 list 的末尾追加元素会导致 copy 整个 list,所以一般都在头部添加元素

Map

如果 key 是原子 ex. %{a: "xx", b: "yy"}; 否则 %{1 => "xx", "a string key" => "yy"}

Binary and Bitstring

长度是 8 的倍数的 Bitstring 也是 Binary

String

Elixir 中的 string 本质就是 Binary

Function

function 在 Elixir 中是一等公民,所以它也可以存放在变量中

Reference

BEAM 实例的引用

pid

Erlang process 的唯一标识

Keywork List

一种 list,每个元素都是一个包含 2 个元素的 tuple

IO List

一种深度自包含的结构,可以用来高效的在处理 IO 和网络数据 ex. 下面这个例子,文件写入时会分成 3 次,因为 a,b,c 的内存地址是不连续的 如果把 a,b,c 拼成一个字符串再写入文件的话,新的字符串会再次分配一次 a,b,c 所占用的内存量

{:ok, file} = :file.open("/tmp/tmp.txt", [:write, :raw])
a = "aaa"
b = "bbb"
c = "ccc"
output = [a, b, c]
:file.write(output)

用 io_list 可以避免上面的问题

{:ok, file} = :file.open("/tmp/tmp.txt", [:write, :raw])
a = "aaa"
b = "bbb"
c = "ccc"
output = [a, [b, [c]]]
:file.write(output)

IO.puts 输出时会拍平 io_list

控制流

一般语言中的流程控制就是判断(if, case…),循环(for, while…) Elixir 中虽然也有 if,case(通过 macro 来实现),但是尽量不要使用

Elixir 中通过模式匹配来实现判断,通过递归来实现循环

模式匹配的例子

通过不同的函数,实现变量的类型判断

defmodule ElixirIntro do
def judge(x) when is_integer(x) do
IO.puts("#{x} is integer")
end def judge(x) when is_bitstring(x) do
IO.puts("#{x} is string")
end def judge(x) do
IO.puts("#{x} is not integer and string")
end
end

递归的示例

递归是 Elixir 中常用的技巧,通过递归可以写出简单易懂的代码 下面示例是累加求和的递归写法

defmodule ElixirIntro do
def sum(n) when n <= 1 do
n
end def sum(n) do
n + sum(n - 1)
end
end

上面的递归写法虽然能完成功能,但是运行过程中消耗的内存很比较大,这种写法就是递归被人诟病的地方。

在 Elixir 中,我们应该使用尾递归的方式来完成循环,因为尾递归会被优化,只占用固定数量的内存,上面的示例如下:

defmodule ElixirIntro do
def sum(total, n) when n <= 1 do
total + n
end def sum(total, n) do
sum(total + n, n - 1)
end
end

所谓尾递归,就是函数在最后只调用了自己

代码组织(模块和函数)

Elixir 的代码用 mix 来管理,通过 mix 创建,管理,发布工程。 代码主要是 module 和 function

$ mix new hello
$ cd hello
$ iex -S mix

Elixir 工程的代码都在 lib 文件夹下。

错误处理

错误处理是 Elixir 中的一级概念。

一般的错误处理思路都是尽可能的捕获错误(可预期和不可预期的):

  • 可预期的错误直接处理
  • 不可预期的错误捕获不到可能系统崩溃,捕获后一般也是直接跳过

Elixir 的核心能力之一是应对高并发,所以它的错误处理思路也不一样。 Elixir 错误处理的目的 不是降低错误的数量 ,而是 降低错误带来的影响 并且能够从错误中 自动恢复 。 所以,Elixir 的处理方式:

  • 可预期的错误,和传统方式一样,尽可能处理
  • 不可预期的错误,直接崩溃重启。会导致崩溃的地方尽快崩溃

Elixir 的观点:

  • 有些错误发生后,要想解决很困难,在发生错误后接着处理可能会导致更严重的错误
  • 很多运行时的错误,极难重现,大部分都能通过重启来解决

总结

Elixir 虽然在它的领域有先天的优势,但是肯定也有不足之处:

  • speed: 性能不是 Erlang 平台的优势,毕竟有一层 BEAM 虚拟机, 高并发 != 高性能
  • ecosystem: Erlang/Elixir 的生态远没有其他语言成熟(比如 java, javascript, ruby 等)

Elixir 不是万能的,但是学习 Elixir 可以打开你的视野,特别是对于一直使用面向对象语言的同学, 学习 Elixir 可以让你以另外一种视角看待程序设计。

Elixir 简介的更多相关文章

  1. Ellxir

    API: elixir https://hexdocs.pm/elixir/Module.html#content API: erlang http://www.cnerlang.com/api.ht ...

  2. elixir mix 简介

    概述 mix 是 elixir 工程的构建工具,利用 mix,可以快速方便的创建 elixir 工程,写单元测试,管理 elixir 包的依赖管理等等. 我觉得刚开始学习 elixir 的时候,先简单 ...

  3. elixir 高可用系列(二) GenServer

    概述 如果我们需要管理多个进程,那么,就需要一个专门的 server 来集中监控和控制这些进程的状态,启停等. OTP 平台中的 GenServer 就是对这个 server 通用部分的抽象. 利用 ...

  4. 写给Java开发者的Node.JS简介

    前言 今天上推特看见这篇文章,点进去发现是新货. 正好最近想入Node的坑,又有一些Java基础,所以希望翻译出来给大家,同时也让自己加深理解. 才疏学浅,如有不妥之处请指正. 原文链接:Node f ...

  5. SpaceVim 语言模块 elixir

    原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属快捷键 交互式编程 运行当前脚本 模块简介 这一模块为 ...

  6. Browsersync 简介 and 使用

    简介 省时的浏览器同步测试工具,Browsersync能让浏览器实时.快速响应您的文件更改(html.js.css.sass.less等)并自动刷新页面. 曾经我们每改一次的代码,都需要手动去刷新一次 ...

  7. ASP.NET Core 1.1 简介

    ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...

  8. MVVM模式和在WPF中的实现(一)MVVM模式简介

    MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...

  9. Cassandra简介

    在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...

随机推荐

  1. Python内置函数(6)——bool

    英文文档: class bool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the st ...

  2. qt集成dsoframer.ocx打开office办公软件

    最近一段时间真是事情太多了,前不久项目中一个嵌入office软件的问题,由于没有时间研究,且项目的需求是浏览word文档,偷了一个懒,把word文档转换成pdf文档,然后嵌入libcef浏览器给打开了 ...

  3. plsql可视化文件夹解释

    function:一般是存储函数或者方法 procedures:一般是存放存储过程 Table:一般是存放建的表 packages:包(头) package bodies:包体types:类型 typ ...

  4. LocalDateTime反序列化,LocalDateTime格式化

    使用mybatis-plus的时候出现了LocalDateTime类(jdk8 中新出现的类 那么我在反序列化的时候出了问题. 我在springboot 2.1.3 中使用以下类结局问题) 用到了下面 ...

  5. Chapter 5 Blood Type——12

    I blinked, my mind going blank. Holy crow, how did he do that? 我眨着眼睛,心里一片空白.天哪,他是怎么做到的? "Er, wh ...

  6. 不能ssh连接ubuntu linux 服务器 secureCRT不能ssh连接服务器 不能远程ssh连接虚拟机的ubuntu linux

    我是用的是secureCRT,远程连接我的虚拟机里面的ubuntu 直接报错,连接不上 1,先分别在windows上ipconfig和ubuntu上ifconfig下 互ping一下,是可以ping通 ...

  7. Python3+Selenium2完整的自动化测试实现之旅(四):Selenium-webdriver操作浏览器、Cookie、鼠标键盘、警示框、设置等待时间、多窗口切换

    本篇学习总结webdriver模块操作浏览器.Cookie.鼠标键盘.警示框.设置等待时间.多窗口切换等方法的使用 1    浏览器控制 Selenium-webdriverAPI提供了对页面元素定位 ...

  8. JavaScript小实例:拖拽应用(二)

    经常在网站别人的网站的注册页中看到一个拖拽验证的效果,就是它的验证码刚开始不出来,而是有一个拖拽的条,你必须将这个拖拽条拖到底,验证码才出来,说了感觉跟没说一样,你还是不理解,好吧,我给个图你看看: ...

  9. 使用Advanced Installer制作IIS安装包(一:配置IIS和Web.config)

    前言:大过年的,写篇文章不容易,还是给自己点个赞~~年前找了下.net安装包的制作方法,发现Visual Studio自带的制作工具使用起来非常麻烦,需要单独下载安装包,并且什么激活认证等等屁事相当麻 ...

  10. Mysql语句中当前时间不能直接使用C#中的Date.Now传输

    MySql中处理字符串时间,会默认把第一个数字当成年份处理. 在C#服务器中,使用Date.Now.ToString()生成的字符串时间,如果不指定字符串格式,C#会按照系统语言输出不同的字符串格式, ...