0x00 说在后面
Erlang读音/rlæŋ/
。第一次见到的时候总感觉怎么读都读不对,起初在维基上看到Erlang标注了音标,能力精确的读出来,而且也没那么怪异。因为工作才有机会接触这门语言,也因而只有三天的工夫能够看《Erlang程序设计》这本书。学习这门语言的时候带着一个工作指标:把一个Erlang日志收集剖析统计的代码转换成Python的。而Erlang的格调是尽量不写正文,尽量在写函数名和变量名的时候表白分明代码的含意。这样一来学习Erlang就成了必要的,很庆幸,领导给了三天工夫学习,三天工夫根本也足够了。除了这一片根底语法的入门篇之外,后续还有一篇或者两篇并发编程和分布式编程的,毕竟这个才是Erlang善于的畛域。话不多说,show me your article
<!--more-->
0x01 配置开发环境
依赖工具:
- Erlang版本:18.3
- IDE:IDEA
下载链接:
- Erlang:https://www.erlang.org/downloads 抉择otp18.3即可。
- IDEA:https://www.jetbrains.com/ide... 抉择社区版即可。
IDEA配置Erlang插件:
- IDEA官网文档-应用IDEA开发Erlang
0x02 基础知识
正文
- % 百分比符号表明正文的开始。
- %% 两个符号通常用于正文函数。
- %%% 三个符号通常用于正文模块。
变量
所有的变量都必须以大写字母结尾,变量只可一次赋值,赋值之后不可在变。 f()函数开释shell绑定变量。
浮点数
- 浮点数必须含有小数点且小数点后必须有一位10进制数
- 用/来除两个整数时相除后果会主动转换成浮点数
- div取整,rem取余
三种标点符号
- 整个函数的定义完结时用一个句号“.”
- 函数参数,数据构建,程序语句之间,用逗号“,”分隔
- 函数定义、
case
、if
、try..catch
、receive
表达式中的模式匹配时,用分号“;”分界
恒等
恒等测试符号 =:=以及不等测试符号 =/=
块表达式
当程序中某处的语法要求只能应用单个表达式然而逻辑上又须要在此应用多个表达式时,就能够应用begin...end快表达式
begin Expr1, ... ExprNend
0x03 内置数据结构
元组及模式匹配(解构)
- _ 代表抛弃的变量,和python雷同
- 匹配时模式匹配符=左右两边的元组的构造必须雷同。
1> Point = {point, 20, 43}.{point,20,43}2> {point, x, y} = Point.** exception error: no match of right hand side value {point,20,43}3> {point, X, Y} = Point.{point,20,43}4> X.205> Y.436> Person = {person, {name, {first, joe}, {last, armstrong}}, {footsize, 42}}.{person,{name,{first,joe},{last,armstrong}},{footsize,42}}7> {_, {_, {_, Who}, {_, _}}, {_, Size}} = Person.{person,{name,{first,joe},{last,armstrong}},{footsize,42}}8> Who.joe9> Size.42
列表
- 列表元素能够是不同的类型。
- 列表头:列表的第一个元素
- 列表尾:列表除第一个元素剩下的局部
竖线符号|
- 将列表的头和尾宰割开来
- [E1, E2, E4, ... , |L]:应用|向列表L的起始处退出多个元素结构成新的列表
- 列表链接操作符 ++ (中断增加操作符)
列表操作演示代码
1> L = [1+7, hello, 2-2, {cost, apple, 30-20}, 3]. [8,hello,0,{cost,apple,10},3]2> L1 = [123, {oranges, 4} | L].[123,{oranges,4},8,hello,0,{cost,apple,10},3]3> [E1 | L2] = L1.[123,{oranges,4},8,hello,0,{cost,apple,10},3]4> E1.1235> L2.[{oranges,4},8,hello,0,{cost,apple,10},3]6> [E2, E3 | L3] = L2.[{oranges,4},8,hello,0,{cost,apple,10},3]7> E3.8
列表表达式
模式:[F(X) || X <- L]
1> L = [1, 2, 3, 4, 5].[1,2,3,4,5]2> [2 * X || X <- L].[2,4,6,8,10]3> [X || {a, X} <- [{a, 1}, {b, 2}, {c, 3}, {a, 4}, hello, "wow"]].[1,4]
字符串
Erlang的字符串是一个整数列表。整数列表的内容由每一个字符对应的ascii码形成
1> I = $s.1152> [I-32, $u, $r, $p, $r, $i, $s, $e]."Surprise"3> $r. 1144> [I-32, $u, $r, $p, 114, $i, $s, $e]."Surprise"
映射组(Map)
映射组是一个由多个Key-Vaule构造组成的合乎数据类型,相似于Python的字典。具体应用如下
1> M1 = #{"name" => "alicdn", "percentage" => 80}.#{"name" => "alicdn","percentage" => 80}2> maps:get("name", M1)."alicdn"3> M2 = maps:update("percentage", 50, M1).#{"name" => "alicdn","percentage" => 50}4> map_size(M1).25> #{"name" := X, "percentage" := Y} = M2.#{"name" => "alicdn","percentage" => 50}6> X."alicdn"7> Y.50
结构映射组和模式匹配时的符号不一样,=>
和:=
的区别。常见的put办法参见erlang maps库的应用。
0x04 模块
- 一个模块寄存于一个.erl文件中(模块名和文件名雷同)
- 编译模块的命令:c(模块名)。编译胜利之后就会加载到以后shell中
- 调用模块中的函数:模块名:函数名(参数)
- 导入模块中的函数:
-import(lists, [map/2, sum/1]).
导出模块中的函数:
- 导出指定函数
-export([start/0, area/2]).
- 导出全副函数
-compile(export_all).
,防止在开发阶段常常会向export中增加函数或者删除函数
- 导出指定函数
-module(learn_test).-author("ChenLiang").%% API-export([area/1]).area({rectangle, Width, Height}) -> Width * Height;area({circle, R}) -> 3.14159 * R * R;area({square, X}) -> X * X.
编译模块,调用函数
1> c(learn_test).{ok,learn_test}2> learn_test:area({circle, 2.0}).12.566363>
0x05 函数
根本函数
同名同目(参数数量,arity)的才是同一个函数。因而函数名雷同,目不雷同的函数是齐全不同的两个函数。同名不同目标函数通常作为辅助函数。
- 函数不会显示地返回值,函数中最初一条语句的执行后果将作为函数的返回值。
- 同一个函数中,并列的逻辑分支之间,用分号 “;” 分界;程序语句之间,用逗号 “,” 分隔。
示例代码:计算列表元素的和
-module(learn_test).-author("ChenLiang").%% API-export([sum/1]).sum(L) -> sum(L, 0).sum([], N) -> N;sum([H|T], N) -> sum(T, H + N).
匿名函数
erlang中的匿名函数就是fun。fun也能够有若干个不同的字句。
1> Z = fun(X) -> 2*X end.#Fun<erl_eval.6.50752066>2> Double = Z.#Fun<erl_eval.6.50752066>3> Double(4).84> TempConvert = fun({c, C}) -> {f, 32 + C * 9 / 5};5> ({f, F}) -> {c, (F - 32) * 5 / 9} 6> end. #Fun<erl_eval.6.50752066>7> TempConvert({c, 100}). {f,212.0}8> TempConvert({f, 212}).{c,100.0}
高阶函数
返回fun或者承受fun作为参数的函数都称为高阶函数。
以fun为参数的函数
常见的是lists模块中的map(Fun, List1) -> List2,filter(Pred, List1) -> List2函数。
lists模块的具体应用参见:https://www.erlang.org/doc/ma...
1> Even = fun(X) -> X rem 2 =:= 0 end.#Fun<erl_eval.6.50752066>2> lists:map(Even, [1, 2, 3, 4, 5, 6]).[false,true,false,true,false,true]3> lists:filter(Even, [1, 2, 3, 4, 5, 6]).[2,4,6]
返回fun的函数
个别在返回的函数外部封装了一些变量和逻辑。通常状况下不写返回fun的函数。
1> Mult = fun(Times) -> (fun(X) -> X * Times end ) end.#Fun<erl_eval.6.50752066>2> Triple = Mult(3).#Fun<erl_eval.6.50752066>3> Triple(4).12
0x06 断言
强化模式匹配的性能,给模式匹配减少一些变量测试和比拟的能力
max(X, Y) when X > Y -> X;max(_, Y) -> Y.
0x07 记录
记录是Erlang中基于元组的key-value数据定义,应用示例如下:
-module(learn_test).-author("ChenLiang").%% API-export([record_test1/0, record_test2/0]).-record(person, {name, age=18, hobby=["erlang"]}). %% record定义能够寄存于hrl和erl中record_test1() -> Person = #person{name="hahaha"}, %% 为record中字段赋值 Person#person.hobby. %% 通过.操作符拜访record中字段record_test2() -> Person = #person{}, #person{name = Name} = Person, %% 通过模式匹配获取record字段 Name. %% 输入undefined
0x08 .hrl头文件
某些文件的扩大名为 .hrl
。这些.hrl
是在 .erl
文件中会用到的头文件,应用办法如下:
-include("File_Name").
例如:
-include("mess_interface.hrl").
.hrl 文件中能够蕴含任何非法的 Erlang 代码,然而通常外面只蕴含一些记录和宏的定义。
0x09 case / if 表达式
case 表达式
case语句语法
case Experssion of Pattern1 [when Guard1] -> Expr_seq1; Pattern2 [when Guard2] -> Expr_seq2; ...end
将Expression的后果和各个Pattern一一匹配,匹配胜利,则计算表达式序列的值,并返回。全副匹配不到,则间接报错。
case语句应用示例:
-module(learn_test).-author("ChenLiang").%% API-export([filter/2]).filter(P, [H|T]) -> case P(H) of true -> [H|filter(P, T)]; false -> filter(P, T) end;filter(_, []) -> [].
在erl shell中运行后果如下:
1> c(learn_test).{ok,learn_test}2> learn_test:filter(fun(X) -> X rem 2 =:= 0 end, [1, 2, 3, 4, 5]).[2,4]
if 表达式
if语句应用示例
-module(learn_test).-author("ChenLiang").%% API-export([bigger/2]).bigger(X, Y) -> if X > Y -> X; X < Y -> Y; true -> -1 end.
如果没有匹配的断言,则会抛出异样。因而最初一个断言通常是true断言。
0x10 异样
Erlang中一切都是表达式,都有返回值,因而异样捕捉语句也有返回值。
捕捉所有的异样_:_
-module(learn_test).-author("ChenLiang").%% API-export([catch_exc1/0,catch_exc2/0]).exception() -> exit({system, "123123"}).catch_exc1() -> try exception() catch _:_ -> 111 end.catch_exc2() -> try exception() catch _ -> 222 end.
erl shell输入后果
1> learn_test:catch_exc1().1112> learn_test:catch_exc2().** exception exit: {system,"123123"} in function learn_test:exception/0 (learn_test.erl, line 17) in call from learn_test:catch_exc2/0 (learn_test.erl, line 28)
多种谬误的检测能够 应用try catch格调。
参考stackoverflow-How do I elegantly check many conditions in Erlang?
记得帮我点赞哦!
精心整顿了计算机各个方向的从入门、进阶、实战的视频课程和电子书,依照目录正当分类,总能找到你须要的学习材料,还在等什么?快去关注下载吧!!!
朝思暮想,必有回响,小伙伴们帮我点个赞吧,非常感谢。
我是职场亮哥,YY高级软件工程师、四年工作教训,回绝咸鱼争当龙头的斜杠程序员。听我说,提高多,程序人生一把梭
如果有幸能帮到你,请帮我点个【赞】,给个关注,如果能顺带评论给个激励,将不胜感激。
职场亮哥文章列表:更多文章
自己所有文章、答复都与版权保护平台有单干,著作权归职场亮哥所有,未经受权,转载必究!