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内置函数(65)——type
英文文档: class type(object) class type(name, bases, dict) With one argument, return the type of an obje ...
- js的异步和单线程
最近,同事之间做技术分享的时候提到了一个问题"js的异步是另开一个线程吗?"当时为此争论不休.会后自己查阅了一些资料,对这个问题进行一个自我的分析与总结,有不同意见的希望可以赐教, ...
- 通过案例了解Hystrix的各种基本使用方式
1 通过一些算术题了解系统发生错误的概率 我们一般用每秒查询率(Query Per Second,简称QPS)来衡量一个网站的流量,QPS是指一台服务器在一秒里能处理的查询次数,它可以被用来衡量服务器 ...
- 『2019/4/8 TGDay1模拟赛 反思与总结』
2019/4/8 TGDay1模拟赛 这次是和高一的学长学姐们一起参加的\(TG\)模拟考,虽然说是\(Day1\),但是难度还是很大的,感觉比\(18\)年的\(Day1\)难多了. 还是看一下试题 ...
- 从锅炉工到AI专家(6)
欠拟合和过拟合 几乎所有的复杂方程都存在结果跟预期差异的情况,越复杂的方程,这种情况就越严重.这里面通常都是算法造成的,当然也存在数据集的个体差异问题. 所以"欠拟合"和" ...
- NIO 简介
上文我们描述了五中IO类型.第一种同步阻塞模型我们我们称之为BIO(Blocking IO), 第三种IO复用模型我们称之为NIO(Nonblocking IO). 上图我们可以很容易的发现 BIO会 ...
- jquery/js知识点收藏
1]关于页面跳转 "window.location.href"."location.href"是本页面跳转 "parent.location.href ...
- linuix没有网络
今天在虚拟机安装玩Centos7以后,update报了一个错 有两个方法可以解决 方法一. 1.打开 vi /etc/sysconfig/network-scripts/ifcfg-ens33(每个机 ...
- arcgis10.0的ArcGIS Services Directory显示401,需要身份验证,访问被拒绝,rest/services需要输入用户名和密码
大家好! 这个错误我也不想说什么,主要是应公司开发需求,从自己的arcgis10.2的版本改为arcgis10.0的版本,装完之后遇到一个错误,老是显示访问被拒绝,我也是找了很多的方式,没有在网上找到 ...
- webpack入门教程--3
webpack打包还可以使用配置文件,我们先创建一个叫做webpack.config.js的文件.这里需要注意一下,这个JS文件的名字不是我们胡乱写的,也是不能更改的,因为webpack 命令执行后, ...