【Erlang】八、模块 & 函数 & 原子在函数参数中的作用

模块

1. 概念

在这之前我们执行所有命令都是在 erlang shell 中运行的,每次只运行了一行代码,但是假如我们想一次运行多行代码怎么办呢?这里就用到了模块

模块的本质就是我们把一个事物所有相关的方法或定义,都写在一个以 .erl 结尾文本中,它就是一个模块

比如矩形有两个公式:

  • 公式1:矩形面积 = 长 * 宽
  • 公式2:周长 = (长 + 宽) * 2

当我们把这两个公式写在一个 名为 rectangle.erl 的文件中时,它就是一个模块了。这样我们再想算矩形的面积时,就不用重复的去写相同的代码了

2. 定义

  • .erl 结尾的文件

  • 假设模块名是 rectangle,文件内第一行必须是

    %% 这个模块的文件名:rectangle.erl
    -module(rectangle)
    

    %% 开头的代表注释,可以理解为备注,在运行代码时,该部分不会被编译,所以可以随便写,这里的注释写的是当前这个模块的文件名

    -module(rectangle) 是固有写法,让erlang执行该模块的代码时,知道这是哪个模块,所以模块名必须和文件的名字一致,并且是模块的第一行代码

    下面我们都已矩形这个例子进行举例


函数

1. 概念

函数可以理解为数学里的公式,给对应的变量传递数值后,可以得到计算后的结果,或让代码执行一段对应的逻辑

2. 定义

函数名(参数1, 参数2, 或者没有参数) ->
	第一行代码,
	第二行代码.
  • 函数名对应了公式的名字
  • () 括号内是传递的参数
  • -> 固定写法,写上就是了
  • , 假设有多行代码时,用 逗号 进行分割
  • 当这个函数(公式)结束后,用

3. 案例解释

案例1:求矩形面积

矩形面积 = 长 * 宽
area = length * width
那么代码里怎么写呢?

%% 计算矩形面积
area(Length, Width) ->	Length * Width.

案例2:求矩形周长

矩形面积 = (长 + 宽) * 2
perimeter = (length * width) * 2
那么代码里怎么写呢?

%% 计算矩形周长, 写法1
perimeter(Length, Width) ->	(Length + Width) * 2.
%% 计算矩形周长,写法2
perimeter(Length, Width) ->
	Param1 = Length + Width,
	Param * 2.

函数的导出

1. 概念

比如我家里有钻石、螺丝刀、扳手,我告诉你我有扳手和螺丝刀
有一天你家里在装修,需要和我借用扳手我直接借给你了
有一天你问我:“哎!你有钻石吗?”,我说:“没有”

假设 钻石、螺丝刀、扳手 是三个函数
我告诉你我有扳手和螺丝刀,就是 导出声明,就是别人都知道,也可以随便用的函数。有变成基础的可以理解为公开方法(public)

2. 定义

%% 格式1:导出一个函数,且该函数不需要传递参数
-export([函数名/0]).
%% 格式2:导出一个函数,且该函数需要传递1个参数
-export([函数名/1]).
%% 格式3:导出一个函数,且该函数需要传递3个参数
-export([函数名/3]).
%% 格式4:导出多个函数, 用逗号分隔不同的函数
-export([函数1/0], [函数2/5], [函数3/2]).

3. 案例:一个完整的矩形模块

%% 模块名:rectangle.erl
%% 矩形相关公式
-module(rectangle).

%% 对外公开的函数,这里只对外公开计算面积的函数
-export([area/2]).

%% 计算矩形面积
area(Length, Width) ->	Length * Width.

%% 计算矩形周长
perimeter(Length, Width) ->	(Length + Width) * 2.

编译

1. 概念

现在我们文件 rectangle.erl 中写的是我们的代码,但是电脑是看不懂的,就比如在中国我们写字用中文,在美国写字用英文,美国人看不懂中文一样,需要翻译一下。翻译的这个过程就是编译

2. 怎么编译

win + r 运行命令窗口

%% 先进入要编译的文件夹的目录;或者先打开文件夹,然后 shfit+右键——在此处打开 powershell 窗口
> cd C:\Work\Erlang
>
%% 运行erlang shell
> erl
> Eshell Vx.x  (abort with ^G)
>
%% 编译 rectangle.erl
> c(rectangle).
%% 提示 perimeter 这个函数内部没有调用,也没有导出
rectangle.erl:12: Warning: function perimeter/2 is unused
%% 编译成功
{ok,rectangle}

在 erlang shell 中调用 c(模块名). 就可以编译模块了,编译成功后,与模块同目录中会多出一个 rectangle.beam 的文件,扩展名 .beam 就是erlang可以运行的模块了


模块的调用

现在erlang可运行的模块已经编译出来了,但是怎么运行呢?

%% 先进入要编译的文件夹的目录
> cd C:\Work\Erlang
>
%% 运行erlang shell
> erl
> Eshell Vx.x  (abort with ^G)
>
%% 求面积:长=12,宽=10
> rectangle:area(12, 10).
120
%% 求面积:长=12132,宽=34234
> rectangle:area(12132, 34234).
415326888
>
%% 求周长:长=10,宽=20
> rectangle:perimeter(10, 20).
%% 这里由于没有导出这个函数,所以报错了
** exception error: undefined function rectangle:perimeter/2

相同函数名,不同参数(重载)

1. 定义

比如矩形包括长方形和正方形,他们的面积都是 长* 宽,但是因为正方形两个边都一样长
所以正方形也可以的面积公式 = 边长 * 边长,我们看代码的实现

%% 模块名:rectangle.erl
%% 矩形相关公式
-module(rectangle).

%% 对外公开的函数,这里只对外公开计算面积的函数
-export([area/1]).

%% 计算长方形面积
area({rectangle, Length, Width}) ->	Length * Width,
%% 计算正方形面积
area({square, Length}) 		 	 ->	Length * Length.

函数 area 有两个子函数,一个对应了正方形面积公式,另一个对应了矩形的面积公式,相同函数名用 , 进行分割,最后用 . 结束,代表整个函数结束了

2. 调用

> erl
> c(rectangle).
{ok,rectangle}
> rectangle:area({rectangle, 2, 3}).
6
> rectangle:area({square, 2}).
4

当一个函数有多个子参数时,erlang会从上向下 用子函数的参数与传递的参数执行模式匹配,直到匹配成功,触发内部逻辑
比如调用 rectangle:area({square, 2}).
erlang 尝试第一个子函数的参数进行模式匹配: {rectangle, Length, Width} = {square, 2}.
匹配失败,
erlang 尝试第二个子函数的参数进行模式匹配:{square, Length}={square, 2}.
等式成立,执行该子函数中的方法:Length * Length.
假若所有的子函数都匹配失败,则会报错

发现了没有,调用参数里默认有一个原子 rectanglesquare
这就是原子的另一个作用:匹配子函数,与表明子函数的具体用途

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值