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进行简单地介 ...
随机推荐
- HBase篇--搭建HBase完全分布式集群
一.前述. 完全分布式基于hadoop集群和Zookeeper集群.所以在搭建之前保证hadoop集群和Zookeeper集群可用.可参考本人博客地址 https://www.cnblogs.com/ ...
- 最近要租房子,用Python看一下房源吧..
前言:最近我的朋友想要租房子,为了装个b,决定运用技术去帮助他. 这个网站是什么我也不知道 反正是一个房子交易网站 http://www.ljia.net/ 设置请求头 headers = {'Ac ...
- qt集成dsoframer.ocx打开office办公软件
最近一段时间真是事情太多了,前不久项目中一个嵌入office软件的问题,由于没有时间研究,且项目的需求是浏览word文档,偷了一个懒,把word文档转换成pdf文档,然后嵌入libcef浏览器给打开了 ...
- OAuth 2.0 授权码请求
关于OAuth 2.0,请参见下面这两篇文章(墙裂推荐): <OAuth 2.0> <Spring Security OAuth 2.0> 纸上得来终觉浅,绝知此事要躬行.理论 ...
- 代理自动配置文件PAC的使用方法
我通常上网使用两个浏览器,safari用于一般上网:Chrome安装SwitchyOmega插件,在不同的代理中切换,来保证某些网站的上网速度. 但是这种方式到了手机上就有点懵,几乎所有的iPhone ...
- 从无到有-在create-react-app基础上接入react-router、redux-saga
搭建项目框架 新建项目 执行如下代码,用create-react-app来建立项目的基础框架,然后安装需要用到的依赖. $ npx create-react-app my-test-project $ ...
- Asp.Net SignalR - 简单聊天室实现
简单聊天室 使用持久链接类我们就可以做一些即时通讯的应用了,我使用Group做了一个简单的聊天室,先上图技术细节下面再讲 可以加入聊天室.创建聊天室.发送消息,下面就说说我是如何通过Group做出来的 ...
- flag.xls
Topic Link http://ctf5.shiyanbar.com/misc/flag.xls 1) 打开表格发现需要密码 但是flag又在表里,但我们可以改他的格式为.txt文本,因为这样就 ...
- [二十]JavaIO之StringReader 与 StringWriter
功能简介 还记得前面说过的CharArrayReader 和 CharArrayWriter吗? CharArray 是数据源 CharArrayReader 是读, 从一个CharArray 中读 ...
- pycharm安装破解go插件
pycharm 2018以前版本安装go插件可以直接在plugins中搜索 go 插件,然后安装.若是2018以后的版本,go 变成了收费插件,plugins 搜不到.然后Google了一下,有人提供 ...