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进行简单地介 ...
随机推荐
- Python3练习
Hello Python3 print("Hello Python!") #print("Hello, Python!"); '''a=1 b=2 c=a+b ...
- Quartz.NET学习笔记(一) 简介
Quartz.NET是一款开源的任务调度框架,他是由Java中的任务调度框架Quartz移植而来的.官方网站https://www.quartz-scheduler.net/. Quartz.Net的 ...
- Python爬虫入门教程 31-100 36氪(36kr)数据抓取 scrapy
1. 36氪(36kr)数据----写在前面 今天抓取一个新闻媒体,36kr的文章内容,也是为后面的数据分析做相应的准备的,预计在12月底,爬虫大概写到50篇案例的时刻,将会迎来一个新的内容,系统的数 ...
- vs2012 aps.net 4.5尚未在web服务器上注册,您需要手动将Web服务器配置为
系统换成Windows10安装VS2012打开项目总提示:vs2012 aps.NET 4.5尚未在web服务器上注册,您需要手动将Web服务器配置为使用ASP.net 4.5,这样您的网站才可能正确 ...
- 为什么使用JDBC操作MySQL需要添加Class.forName("com.mysql.jdbc.Driver")
引言 如果熟悉使用JDBC来连接数据库的同学一定很清楚连接数据库的代码中一定会有依据Class.forName("com.mysql.jdbc.Driver"); public s ...
- 使用mpvue开发小程序教程(三)
在上一篇文章中,我们熟悉了一下通过vue-cli生成的mpvue工程代码骨架的基本结构,大致了解了每一个部分的代码到底要放到何处.从本文起我们就开始涉及真正的编码部分,学习使用Vue的语法去编写小程序 ...
- linux下的powerline安装教程
powerline是一款比较炫酷的状态栏工具,多用于vim和终端命令行.先上两张效果图,然后介绍一下具体的安装教程. 图 1 powerline在shell下的效果图 图 2 powerline在vi ...
- XSS Reflected 测试
由于最近在做XSS方面的测试,于是找到了DVWA平台进行实验测试,通过这三篇文章让大家了解XSS方面的大概内容,这三篇文章只是把你领进XSS的大门,要想真正深入的学习XSS,你还需要去学习很多东西来提 ...
- centos7正确关机重启
linux主要用于服务器领域,而在服务器上执行一项服务是永无止境的,除非遇到特殊情况,否则不会关机.和Windows不同,在linux系统下,很多进程是在后台执行的.在屏幕背后,可能有很多人同时在工作 ...
- curl 错误总结
证书域名与访问的域名不一致 问题:curl SSL: certificate subject name 'luffichen_server.tencent.com' does not match ta ...