Elixir 简介
概述
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 简介的更多相关文章
- Ellxir
API: elixir https://hexdocs.pm/elixir/Module.html#content API: erlang http://www.cnerlang.com/api.ht ...
- elixir mix 简介
概述 mix 是 elixir 工程的构建工具,利用 mix,可以快速方便的创建 elixir 工程,写单元测试,管理 elixir 包的依赖管理等等. 我觉得刚开始学习 elixir 的时候,先简单 ...
- elixir 高可用系列(二) GenServer
概述 如果我们需要管理多个进程,那么,就需要一个专门的 server 来集中监控和控制这些进程的状态,启停等. OTP 平台中的 GenServer 就是对这个 server 通用部分的抽象. 利用 ...
- 写给Java开发者的Node.JS简介
前言 今天上推特看见这篇文章,点进去发现是新货. 正好最近想入Node的坑,又有一些Java基础,所以希望翻译出来给大家,同时也让自己加深理解. 才疏学浅,如有不妥之处请指正. 原文链接:Node f ...
- SpaceVim 语言模块 elixir
原文连接: https://spacevim.org/cn/layers/lang/elixir/ 模块简介 功能特性 启用模块 快捷键 语言专属快捷键 交互式编程 运行当前脚本 模块简介 这一模块为 ...
- Browsersync 简介 and 使用
简介 省时的浏览器同步测试工具,Browsersync能让浏览器实时.快速响应您的文件更改(html.js.css.sass.less等)并自动刷新页面. 曾经我们每改一次的代码,都需要手动去刷新一次 ...
- ASP.NET Core 1.1 简介
ASP.NET Core 1.1 于2016年11月16日发布.这个版本包括许多伟大的新功能以及许多错误修复和一般的增强.这个版本包含了多个新的中间件组件.针对Windows的WebListener服 ...
- MVVM模式和在WPF中的实现(一)MVVM模式简介
MVVM模式解析和在WPF中的实现(一) MVVM模式简介 系列目录: MVVM模式解析和在WPF中的实现(一)MVVM模式简介 MVVM模式解析和在WPF中的实现(二)数据绑定 MVVM模式解析和在 ...
- Cassandra简介
在前面的一篇文章<图形数据库Neo4J简介>中,我们介绍了一种非常流行的图形数据库Neo4J的使用方法.而在本文中,我们将对另外一种类型的NoSQL数据库——Cassandra进行简单地介 ...
随机推荐
- Python内置函数(6)——bool
英文文档: class bool([x]) Return a Boolean value, i.e. one of True or False. x is converted using the st ...
- qt集成dsoframer.ocx打开office办公软件
最近一段时间真是事情太多了,前不久项目中一个嵌入office软件的问题,由于没有时间研究,且项目的需求是浏览word文档,偷了一个懒,把word文档转换成pdf文档,然后嵌入libcef浏览器给打开了 ...
- plsql可视化文件夹解释
function:一般是存储函数或者方法 procedures:一般是存放存储过程 Table:一般是存放建的表 packages:包(头) package bodies:包体types:类型 typ ...
- LocalDateTime反序列化,LocalDateTime格式化
使用mybatis-plus的时候出现了LocalDateTime类(jdk8 中新出现的类 那么我在反序列化的时候出了问题. 我在springboot 2.1.3 中使用以下类结局问题) 用到了下面 ...
- Chapter 5 Blood Type——12
I blinked, my mind going blank. Holy crow, how did he do that? 我眨着眼睛,心里一片空白.天哪,他是怎么做到的? "Er, wh ...
- 不能ssh连接ubuntu linux 服务器 secureCRT不能ssh连接服务器 不能远程ssh连接虚拟机的ubuntu linux
我是用的是secureCRT,远程连接我的虚拟机里面的ubuntu 直接报错,连接不上 1,先分别在windows上ipconfig和ubuntu上ifconfig下 互ping一下,是可以ping通 ...
- Python3+Selenium2完整的自动化测试实现之旅(四):Selenium-webdriver操作浏览器、Cookie、鼠标键盘、警示框、设置等待时间、多窗口切换
本篇学习总结webdriver模块操作浏览器.Cookie.鼠标键盘.警示框.设置等待时间.多窗口切换等方法的使用 1 浏览器控制 Selenium-webdriverAPI提供了对页面元素定位 ...
- JavaScript小实例:拖拽应用(二)
经常在网站别人的网站的注册页中看到一个拖拽验证的效果,就是它的验证码刚开始不出来,而是有一个拖拽的条,你必须将这个拖拽条拖到底,验证码才出来,说了感觉跟没说一样,你还是不理解,好吧,我给个图你看看: ...
- 使用Advanced Installer制作IIS安装包(一:配置IIS和Web.config)
前言:大过年的,写篇文章不容易,还是给自己点个赞~~年前找了下.net安装包的制作方法,发现Visual Studio自带的制作工具使用起来非常麻烦,需要单独下载安装包,并且什么激活认证等等屁事相当麻 ...
- Mysql语句中当前时间不能直接使用C#中的Date.Now传输
MySql中处理字符串时间,会默认把第一个数字当成年份处理. 在C#服务器中,使用Date.Now.ToString()生成的字符串时间,如果不指定字符串格式,C#会按照系统语言输出不同的字符串格式, ...