1.Erlang介绍
Index - Erlang/OTP
Erlang是一种通用的面向并发的编程语言
Erlang是一个结构化,动态类型编程语言,内建并行计算支持
使用Erlang来编写分布式应用要简单的多,因为它的分布式机制是透明的
1.1 为什么选择Erlang
- 需要处理大量并发活动
- 需要在计算机网络上分发
- 需要跨越多个服务器
- 且在一点时间范围内对用户做出响应
1.2 Erlang的特点
- 并发:Erlang采用轻量级进程模型,支持高并发。
- 容错:内置“让进程崩溃”机制,通过进程监控和重启来实现容错。
- 分布式:支持跨节点通信,适合分布式系统开发。
- 函数式编程:以不可变数据和递归为核心,强调函数式编程范式。
- 热代码升级:支持在不中断服务的情况下更新系统代码。
- 垃圾回收:每个进程有独立的垃圾回收机制,减少了停顿时间
1.3 发展前景
Erlang语言在并发、分布式系统和高可用性方面有着独特优势,尤其适用于电信、金融和实时系统等领域
尽管其市场份额较小,但随着云计算、物联网(IoT)和微服务架构的发展,Erlang的前景仍然看好
其强大的容错机制和并行处理能力使得它在处理大规模并发请求时非常高效
2. 环境设置
win10 64位系统 搭建 erlang + vscode 开发环境_vscode安装erlang-CSDN博客
3.第一个helloworld
- %符号用于向程序添加注释
- module语句就像在任何编程语言中添加命令空间一样。在这里,我们要提到的是,这段代码将是一个名为helloworld的模块的一部分
- 使用export函数可以使用程序中定义的任何函数。我们正在定义一个名为helloworld的函数,为了使用helloworld函数,我们必须使用export语句。/0表示我们的函数‘start’ 接受0参数
- 我们最终定义了helloworld函数。这里我们使用另一个名为io的模块,它在Erlang中具有所有必需的输入输出函数。我们使用fwrite函数将“Hello World”输出到控制台
3.1 声明的一般形式
连字符(–)通常与模块,导入和导出语句一起使用
-module(helloworld).
-export([start/0]).
Erlang中的每个语句都需要以(.)符号结尾
io:fwrite("Hello, world!\n").
斜杠(/)符号与函数一起使用,以定义函数接受的参数数量。
-export([start/0]).
3.2 模块
在Erlang中,所有代码都分为模块。模块由一系列属性和函数声明组成。就像其他编程语言中的名称空间的概念一样
语法:ModuleName需求是相同的文件名减去扩展.erl。否则,代码加载将无法按预期进行。
-module(ModuleName).
-module(helloworld).
3.2 导入声明
如果要使用现有Erlang模块的功能,则可以使用import语句
-import (modulename, [functionname/parameter]).
3.5 Erlang中的关键字
4.EShell
Erlang Shell用于测试表达式。因此,在实际在应用程序本身中进行测试之前,可以非常轻松地在外壳中进行测试
ctrl+a:光标会移至该行的开头
ctrl+e : 光标会移动至行的末尾
ctrl+d : 删除当前光标所在的字符
ctrl+f(右方向键):光标向右移动
ctrl+b(左方向键):光标向左移动
ctrl+p(上方向键):上一行
ctrl+n(下方向键):下一行
ctr+t:调换最近2个字符
tab:智能补齐(li-->lists)
- c("Mod"). 表示编译一个模块,生成beam文件
- Mod:模块中的函数(). 表示执行这个函数
- halt(). 表示结束这个Eshell
5.Erlang基础知识
5.1 注释
- % 标明注释的开始
- %% 注释函数
- %%% 注释模块
5.2 变量
所有的变量都必须以大写字符开头,变量只可赋值一次,赋值之后不可再变,f()函数释放shell绑定变量
5.3 三种标点符号
recodr_test2()->
Person = #person{},
#Person{name = Name} = Person,%%通过模板匹配获取record字段
Name. %% 输出undefined
- 整个函数定义结束是用一个句号"."
- 函数参数,数据构建,顺序语句之间,用逗号","分割
- 函数定义,case,if,try...catch,receive表达式中的模式匹配时,用分号";" 定界
简单的来说就是语句结束用. 语句顺序执行用, 语句并列执行用;
5.4 恒等
恒等测试符号=:=
以及不等测试符号= / =
5.5 块表达式
当程序中某处的语法要求只能使用单个表达式,但是逻辑上又需要在此处使用多个表达式时,就可以使用begin...end块表达式
begin
Expr1,
...
ExprN
end
6. 函数与模块
模块是 erlang 的基本单元。
模块保存在扩展名为 .erl 的文件里。必须先编译才能运行,编译后的模块以 .beam 作为扩展名。
子句没有返回语句,则最后一条表达式的值就是返回值
编译: 使用c(模块),就会生产.beam文件,再使用demo:函数,就能调用函数了
7. 数据类型
7.1 数值类型
7.1.1 整数
- 正数 101
- 负数 -101
- 十六进制数字16#9A
- 二进制数字 2#1010
- ASCII码查询$9(查询数字9的ASCII码)
7.1.2 浮点数
- 正数3.14
- 负数-0.1223
- 科学计数法6.23e^-11
7.1.3 原子类型(有名字的常量)
原子类型就是一个字面量,一个有名字的常量,如:hello,phone_number.
原子类型的值如果不以小写字母开头或者该值中间包含除字母,数字,下划线,@,之外的其他字符,那么就必须用单引号括起来,如:"Mobile_phone" "empty box","
原子类型的值与变量不同,变量拥有值,而原子类型没有
7.2 元组
元组是一个复合类型,可以包含多个不同类型的元素,元组中也可以嵌套元组
erlang语言的元组下标是从1开始的
{admin,24,{july,24}}
对元组进行操作的函数示例如下:
- element(). %得到元组中某个下标的元素
- setelemet(). %修改元组中某个下标的元素
- tuple_size(). %得到元组的长度
7.2.1 案例
一个简单的实例:将厘米变成英寸,将英寸变成厘米的函数
解释上面函数:convert_length中的参数centimeter是原子类型,也就是一个有名字的常量
X是大写的参数,即是变量
在调用函数时,会先进行匹配这个函数的参数,比如:
7.3 列表与字符串
列表与元组类似,都是复合类型
字符串是特殊的列表,可以看做是一个一个字符组成的列表
列表用方括号表示,列表与元组相似,但是元组只能在比较中使用,而列表运行执行的操作更多
字符串实际上是特殊类型的列表,Erlang不支持字符串的概念,但是可以使用双引号创建字符串值
字符串实际上只是由ASCII字符值组成的列表,因此,上面的字符串存储为由ASCII字符值组成的列表
列表中的元素可以在合理的地府换行,但是不允许在一些"不合理的地方",比如原子类型,整数,或者其他数据类型的中间换行,
[{moscow,{c,-10}},{cape_town,{f,70}},{stockholm,{c,
-1}}]. %正确
[{moscow,{c,-10}},{cape_to
wn,{f,70}},{stockholm,{c,-1}}]. %错误
简洁一点就是:建议在,后面换行
7.3.1 | 操作
在Erlang中构造一个列表使用|(管道) 操作符,分割头(列表开头)和尾,表示为[Head | Tail],头饰单一元素,尾是列表的其余部分,例如可以使用“|”查看部分列表
[1 | [2,3]]. %在列表的开头添加新的值
[1,2,3] ++ [4,5]. %使用++连接2个列表
[1,2,3,4,5] -- [4,5]. %使用--删除右边列表的所有元素(符合条件时)
- 同理字符串也有这样的操作,erlang不支持字符串,但把它当成特殊的列表
7.3.2 翻转一个列表
7.4 函数
7.4.1 基本函数
在erlang中函数不会显示地返回值,函数中最后一条语句的结果将作为函数的返回值
同一个函数中,并列逻辑分支之间,用分号;分界,顺序语句之间,用逗号,分割
定义即调用基本函数示例:
- erlang编译器在调用函数时,会进行模式匹配选择最合适的函数分支调用
计算列表中所有元素和
7.4.2 匿名函数
Erlang中fun就是匿名函数,fun的简单使用
当然也可以多分支使用
7.4.3 高阶函数
返回fun或者以fun作为参数的函数都称为高阶函数
- 其中lists:map(函数1,列表2) 表示列表2中所有元素带入函数1
返回fun函数
一般在返回的函数内部封装了一些变量和逻辑,通常情况下不写返回fun的函数
7.5 模式匹配
erlang通过模式匹配把变量绑定到值,模式匹配发生在函数调用,赋值等操作中,Erlang中的变量必须以大写字符开头,后面是大写字母,小写字母和下划线的任意组合。
且不可修改,但能通过f(变量)进行释放
- 下划线_表示占位符,
7.6 映射
多个key-value组成的复合数据类型
映射的语法格式如下:
#{key1=>Value1,....,KeyN=>ValueN}
- 一个key-value称为一个关联对,
- 关联对中的key或value称为元素,
- 关联对的个数称为映射的size
Erlang内置了丰富的函数来操作map,如下所示:
- maps:get().%取映射key中对应的value
- maps:update().%更新映射中key对应的value
- map_size(). %得到映射中键值对的个数
8. 输出到终端
使用io:format 输出到终端
~n : 输出一个换行符(自动匹配平台标准)
~p : 参数打印成为美观
~s:输出一个字符串,I/O列表或原子,打印时不带引号
~w : 用标准语法输出erlang的数据类型
~f:输出浮点数,~.kf表示输出保留k位小数的浮点数
下面是一个简单案例,来说明如何使用io:format函数
- ~-4s表示先左对齐,总位数为4位,打印字符串
- ~-4.1s表示先左对齐,总位数为4位,但精度为1(有效数字)打印字符串
- ~-4.1.+s表示先左对齐,总位数为4位,但精度为1(有效数字),不够位数用+代替,打印字符串
9 case语句语法(匹配值或参数)
case expression of
value1 -> statement#1;
value2 -> statement#2;
valueN -> statement#N
end.
- 注意:如果case语句都没有匹配成功的话,会报出异常,
10. if 语句(真假值或参数)
- 从上到下,只要一个成功,就退出了,
- 注意:如果if语句都没有匹配成功的话,会报出异常, 因此需要一个恒为真的条件
11.内置函数
内置函数常常实现那些在Erlang中不容易实现或者在Erlang中实现效率不高的函数,
内置函数是指在Erlang虚拟机中存在的函数,常用内置函数无需使用erlang:的形式调用,但不是所有的内置函数都在Erlang模块中
11.1 类型转换
函数名 | 说明 | 举例 |
atom_to_list/1 | 原子转列表 | 1>atom_to_list(hello). "hello" |
list_to_atom/1 | 列表转原子 | 1>list_to_atom("hello"). hello |
float_to_list/1 | 浮点转列表 | 1>float_to_list(7.0). "7.00000000000e+00" |
list_ot_float/1 | 列表转浮点 | 1>list_to_float("7.0003+00") |
integer_to_list/1 | 整型转列表 | 1>integer_to_list(77). "77" |
list_to_integer/1 | 列表转整型 | 1>list_to_integer("77"). 77 |
tuple_to_list/1 | 元组转列表 | 1>tuple_to_list("a,b,c"). [a,b,c] |
list_to_tuple/1 | 列表转元组 | 1>list_to_tuple([a,b,c]). {a,b,c} |
11.2 类型判断
函数 | 说明 |
is_number(X) | X是一个整数或浮点数 |
is_integer(X) | X是一个整数 |
is_float(X) | X是一个浮点数 |
is_atom(X) | X是一个原子 |
is_tuple(X) | X是一个元组 |
is_list(X) | X是一个列表 |
is_map(X) | X是一个映射 |
is_record(X,Tag) | X是一个类型为Tag的记录 |
is_record(X,Tag,N) | X是一个类型为Tag,大小为N的记录 |
is_function(X) | X是一个fun |
is_function(X,N) | X是一个带有N个参数的fun |
is_constant(X) | X是一个常量 |
11.3 常用函数
函数 | 说明 |
abs(Number) | 求绝对值 |
element(N,Tuple) | N是否是元组的元素 |
float(Term) | 转成一个浮点数,Term必须是一个数字 |
round(Number) | 将X转换成一个整数 |
hd(List) | 返回列表头 |
tl(List) | 返回列表尾 |
length(List) | 求列表的长度 |
self() | 返回当前进程标识符 |
size(X) | X的大小,它可以是一个元组或二进制型 |
trunc(Number) | 将X去掉小数,取整 |
tuple_size(Tuple) | 元组的大小 |
time() | 获取时间 |
12. 创建并启动一个进程
使用spawn()创建一个进程,使用start()启动进程
相较于其他编程语言,Erlang的优势在于它的并发程序设计与分布式程序设计,
并发是指一个程序中同时有多个线程执行,
Erlang的内置函数spawn可以用来创建一个新的进程,语法格式如下:
spawn(模块,函数,[参数])
======================================================================
不再更新....