zoukankan      html  css  js  c++  java
  • Programming Erlang 学习笔记(一)

    入门

    启动Shell

    在cmd中输入命令”erl”,百分号(%)表示一个注释的开始,从百分号开始到这行结束的所有文本都被看做是注释。

    一个完整的命令需要以一个句点和一个回车结束。

    退出erlang的命令是q().

    命令 f() 会让 shell释放它所绑定过的所有变量。即所有的变量都编程自由变量。

    变量

    所有的变量必须以大写字母开头。

    Eralng的变量只能被赋一次值,第二次赋值会出现匹配失败的错误。一个变量如果含有一个被赋予的值,就称为绑定变量,否则称为自由变量。一开始所有变量都是自由的。

    在Erlang中,=表示一个模式匹配操作。

    浮点数

    “/”永远返回浮点数,因此,4/2计算结果就是2.0000. N div M 和 N rem M 是用于整数除和取余数

    原子

    Erlang中的原子是全局有效的,而且无需使用宏定义或者包含文件.

    原子是一串以小写字母开头,后跟数字字母或下划线或邮件符号的字符(句点也能在原子中使用,但这不是一个正规的Erlang扩展),例如,red,december,cat,meters.

    使用单引号引起来的字符也是原子.一个原子的值就是原子自身.

    元组

    在声明元组时,就自动创建了元组,不再使用它们时,元组也随之销毁.

    创建数据结构时不能引用未定义的变量.

    F={firstName, joe} –> {firstName, joe}

    L= {lastName, armstrong} –> {lastName, armstrong}

    P = {person , F, L} –> {person, {firstName, joe}, {lastName, armstrong} }

    通过模式匹配操作符=,从元组中提取一些字段值。

    Point = {point, 10, 45}. {point, X, Y} = Point –> X = 10,  Y = 45.

    _ 称为占位符,表示不关心的变量。

    列表

    list的第一个元素是head,其他元素组合起来称为tail. [H | T] 是一个 list, H 为 head, T为tail. | 可以将head和tail分隔. []是空 list

    字符串

    字符串实际就是一个整数列表,必须用双引号。

    可以使用$符号表示字符的整数值。

    字符串中的字符是Latin-1(ISO-8859-1)编码的字符。

    顺序型编程

    模块

    模块代码文件的后缀名为.erl,编译成功后的扩展名为.beam.

    shell中 pwd() 可以打印出当前的工作目录,cd(Dir)可以将当前目录切换到Dir所在目录,使用正斜杠来分割目录名. cd(“d:/code/erlang”)

    示例程序 shop

    -module(shop).
    -export ([cost/1]).
    cost(oranges) -> 5;
    cost(newspaper) -> 8;
    cost(apples) -> 2;
    cost(pears) -> 9;
    cost(milk) -> 7.

    示例程序 shop1

    -module (shop1).
    -export([total/1]).
    
    total([{What, N} | T]) -> shop:cost(What) * N + total(T);
    total([]) -> 0.

    fun

    fun就是匿名函数。

    示例

    Z = fun(X -> 2*X end.
    
    Double = Z.
    
    Hypot = fun(X, Y) -> math:sqrt(X*X + Y*Y) end.
    
    TempConvert = fun({c, C}) -> {f, 32 + C*9/5};
            ({f, F}) -> {c, (F-32)*5/9}
            end.

    能够返回fun 或 接受 fun作为参数的函数,都被称作高阶函数(high-order function)

    示例二:以fun为参数的函数

    L = [1,2,3,4].
    lists:map(Double, L).
    
    Even = fun(X) -> (X rem 2) =:= 0 end.
    lists:map(Even, [1,2,3,4,5,6,7,8]).
    lists:filter(Even, L).

    =:=是一个恒等测试符号.

    示例三:返回fun的函数

    Fruit = [apple, orange, pear].
    MakeTest = fun(L) -> (fun(X) -> lists:member(X, L) end) end.
    IsFruit = MakeTest(Fruit).
    IsFruit(apple).
    IsFruit(hbccdf).
    IsFruit(peer).
    
    lists:filter(IsFruit, Fruit).
    lists:filter(IsFruit, [hbccdf, peer, apple. dog]).

    示例三:自定义for循环结构

    %自定义for循环结构一
    for(Max, Max, F) -> [F(Max)];
    for(I, Max, F) -> [F(I) | for(I + 1, Max, F)].
    
    %自定义for循环结构二
    for1(true, I, Condition, I_Operation, F) -> [F(I)];
    for1(false, I, Condition, I_Operation, F) -> [F(I) | for1(Condition(I), I_Operation(I), Condition, I_Operation, F)].
    for(I, Condition, I_Operation, F) -> [F(I) | for1(Condition(I), I_Operation(I), Condition, I_Operation, F)].
    
    hbccdf:for(1, 10, fun(I) -> I end).
    
    Condition = fun(I) I=:=10 end.
    I_Operation = fun(I) I+1 end.
    hbccdf:for(I, Condition, I_Operation, fuc(I) -> I * I end).

    简单的列表处理

    示例四:map

    map(_, []) -> [];
    map(F, [H| T]) -> [F(H)| map(F, T)].

    map的第一个子句表示该对一个空列表做什么处理。把任何函数映射到一个空列表上只能产生一个空列表。

    示例五:改进版total

    %改进版total
    total(L) ->
        sum(map(fun({What, N}) -> shop:cast(What) * N end, L)).

    声明-import(lists,[map/2, sum/1])意味着函数map/2是从lists模块中导入的。没有事说可以用map(Fun, ...)而不必去写lists:map(Fun,...)。没有在导入中声明,就必须使用完整的名称“模块:函数”。

    声明-export([total/1])意味着函数total/1能够在模块之外调用,只有从一个模块中到处的函数才能在模块之外调用。

    列表解析

    示例六:

    [2*X || X <- L].
    
    Buy = [{oranges, 4}, {newspaper, 1}, {apples, 10}, {pears, 6}, {milk, 3}].
    [{Name, 2*Number} || {Name, Number} <- Buy].

    [F(X) || X <- L] 代码“由F(X)组成的列表,其中X是取值于列表L”

    || 右边的元组{Name,Number}适用于匹配列表Buy中每个元素的 模式。左边的元组{Name, 2*Number}则是一个构造器

    示例七:改进版total三

    %改进版total三
    total(L) ->
        sum([shop:cost(What) * N || {What, N} <- L]).

    示例八:快速排序

    qsort([]) -> [];
    qsort([P|T]) -> qsort([X || X <- T, X < P]) ++ [P] ++ qsort([X || X <- T, X >= P]).

    ++操作用于拼接两个list,类似C#中的字符串拼接

    示例九:毕达哥拉斯三元组

    pythag(N) ->
        [{A, B, C} || 
            A <- lists:seq(1, N),
            B <- lists:seq(1, N),
            C <- lists:seq(1, N),
            A + B + C =< N,
            A * A + B * B =:= C * C].

    lists:seq(1,N)返回一个由1到N整数组成的列表,所以A<-lists:seq(1,N)意味着A的取回范围是1到N的所有整数,所以可以这么理解“从1到N中得到A、B、C的所有可能取值,使得A+B+C小于等于N且A*A + B*B = C*C”.

    12> lib2:pythag(15).
    [{3,4,5},{4,3,5}]
    13> lib2:pythag(30).
    [{3,4,5},{4,3,5},{5,12,13},{6,8,10},{8,6,10},{12,5,13}]

    示例十:变位词

    perms([]) -> [[]];
    perms(L) -> [[H|T] || H <- L, T <- perms(L--[H])].

    X--Y是列表的分离操作符,它从列表X中分离出元素Y,执行结果如下

    2> lib2:perms("123").
    ["123","132","213","231","312","321"]
    3> lib2:perms("abcd").
    ["abcd","abdc","acbd","acdb","adbc","adcb","bacd","badc",
     "bcad","bcda","bdac","bdca","cabd","cadb","cbad","cbda",
     "cdab","cdba","dabc","dacb","dbac","dbca","dcab","dcba"]

    算数表达式

    算数表达式

  • 相关阅读:
    理解maven命令package、install、deploy的联系与区别
    Mybatis中传参包There is no getter for property named 'XXX' in 'class java.lang.String'
    Spring boot 外部资源配置
    配置spring boot 内置tomcat的accessLog日志
    spring使用@Value标签读取.properties文件的中文乱码问题的解决
    使用Lombok简化你的代码
    统计mysql数据库中数据表/字段等数量的sql
    Kettle
    Python内置函数(39)——locals
    Python内置函数(38)——list
  • 原文地址:https://www.cnblogs.com/hbccdf/p/3485452.html
Copyright © 2011-2022 走看看