Erlang 模塊與函數(shù)

2022-07-07 15:25 更新

模塊與函數(shù)

如果一種編程語言只能通過 shell 來運行代碼,那么這種語言基本上沒什么太大的用處,Erlang 同樣可以通過腳本來運行程序。這里有一小段 Erlang 程序。使用合適的文本編輯器將其輸入到文件 tut.erl 中。文件名稱必須為 tut.erl 不能任意修改,并且需要將其放置于你啟動 erl 命令時所在的目錄下。如果恰巧你的編輯器有 Erlang 模式的話,那么編輯器會幫助你優(yōu)雅地組織和格式化你的代碼 (參考 Emacs 的 Erlang 模式),不過即使你沒有這樣的編輯器你也可以很好地管理你自己的代碼。Number、ShoeSize 和 Age 都是變量。

創(chuàng)建模塊和調(diào)用函數(shù):

模塊是 erlang 的基本單元。
模塊保存在擴展名為 .erl 的文件里。必須先編譯才能運行,編譯后的模塊以 .beam 作為擴展名。
子句沒有返回語句,則最后一條表達式的值就是返回值。

  1. -module(geometry). %模塊聲明,模塊名必須與文件名相同。
  2. -export([area/1]). %導(dǎo)出聲明,聲明可以外部使用的函數(shù)
  3. area({rectangle, Width, Height}) -> Width*Height; %子句1
  4. area({square, Side}) -> Side * Side.%子句2

這個函數(shù) area 多個子句,子句之間用;分開。

編譯

在控制臺中,使用 c(geometry).可以對 geometry.erl 進行編譯。
在當(dāng)前目錄生成對應(yīng)的 geometry.beam 文件。

  1. 17> c("ErlangGame/geometry.erl").
  2. ErlangGame/geometry.erl:1: Warning: Non-UTF-8 character(s) detected, but no encoding declared. Encode the file in UTF-8 or add "%% coding: latin-1" at the beginning of the file. Retrying with latin-1 encoding.
  3. {ok,geometry}

路徑

c 的參數(shù),是文件名。帶不帶擴展名 .erl 都可以。是絕對路徑,相對路徑,都可以。
例如我的目錄是 e:/mywokespace/ErlangGame/geometry.erl

  1. c("e:/mywokespace/ErlangGame/geometry.erl").%使用絕對路徑
  2. c("ErlangGame/geometry.erl").%使用相對路徑,這個時候我所在的目錄是e:/mywokespace/
  3. c(geometry).%使用相對路徑、去掉雙引號。因為沒有.號,可以使用原子。

編譯的輸出了警告:

ErlangGame/geometry.erl:1: Warning: Non-UTF-8 character(s) detected, but no encoding declared. Encode the file in UTF-8 or add "%% coding: latin-1" at the beginning of the file. Retrying with latin-1 encoding.

這是因為我寫了注釋,注釋是漢字,使用了 UTF-8。去掉的話,就會:
{ok,geometry}
只有這個了。
編譯之后,調(diào)用模塊是不用加這個路徑了。

fun:基本抽象單元

定義一個函數(shù)

  1. 1> Double = fun(x)->2*x end.
  2. #Fun<erl_eval.6.52032458>
  3. 2> Double(2).
  4. ** exception error: no function clause matching
  5. erl_eval:'-inside-an-interpreted-fun-'(2)

函數(shù)定義是成功了,但是怎么調(diào)用都報錯。
試了好久好久,突然發(fā)現(xiàn)x是小寫的。在 Erlang 里面,x 就相當(dāng)于 C++ 的 'x'。是不能做變量的。
變量都是大寫開頭的。

  1. 3> Three = fun(X)-> 3 * X end.
  2. #Fun<erl_eval.6.52032458>
  3. 4> Three(2).
  4. 6

ok。成功了。

函數(shù)可以作為參數(shù)

  1. 5> L = [1,2,3,4].
  2. [1,2,3,4]
  3. 6> lists:map(Three, L).
  4. [3,6,9,12]

這里調(diào)用了標(biāo)準(zhǔn)庫的模塊。標(biāo)準(zhǔn)庫是已經(jīng)編譯好的,可以直接使用。
直接把函數(shù)名傳進去就行了。
lists:map 相當(dāng)于 for 循環(huán)


=:=測試是否相等。

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

llists:filter 根據(jù)條件過濾列表的元素。

函數(shù)作為返回值

  1. 9> Fruit = [apple, pear, orange]. %創(chuàng)建一個列表
  2. [apple,pear,orange]
  3. 10> MakeTest = fun(L)->(fun(X)->lists:member(X,L) end) end.%創(chuàng)建一個測試函數(shù)。
  4. #Fun<erl_eval.6.52032458>
  5. 11> IsFruit = MakeTest(Fruit).%這里不是函數(shù)聲明,而是匹配了MakeTest的返回值。
  6. #Fun<erl_eval.6.52032458>
  7. 12> IsFruit(pear).%調(diào)用函數(shù)
  8. true
  9. 13> lists:filter(IsFruit, [dog, orange, cat, apple, bear]).%過濾
  10. [orange,apple]

MakeTest 內(nèi)聲明了一個函數(shù),因為是最后一個語句,所以被作為返回值。
在模塊里面加個函數(shù)

  1. -module(test). %模塊聲明,模塊名必須與文件名相同。
  2. -export([area/1,test/0,for/3]). %導(dǎo)出聲明,聲明可以外部使用的函數(shù)
  3. area({rectangle, Width, Height}) -> Width*Height; %子句
  4. area({square, Side}) -> Side * Side.
  5. test() ->
  6. 12 = area({rectangle, 3, 4}),
  7. 144 = area({square, 13}),
  8. tests_worked.


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號