2011-02-08 38 views
4

如何在Erlang中用方法等(如整數比較)定義一些對象的類(或類型)?Erlang:用方法和字段定義一些對象類

如何我舉個例子,這樣做:

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

如果我想整理一些對象,例如人的名單。

+1

寫下你的'qsort`來取比較器`fun`並在體內使用它,而不是`= <` and `>`。 – 2011-02-08 15:29:00

+1

希望你意識到你選擇了「錯誤的」答案......如果你遵循高票投票答案的建議,你會爲自己提供更好的服務 – 2011-02-09 10:41:40

回答

9

非常快速的回答:你不想去那裏。

更長的回答:Erlang不是Java的「傳統意義上的」面向對象的語言。但它有幾種機制可能作爲對象的替身:首先是關閉,它可以很容易地編碼對象的等價物,儘管編碼是如此笨拙以至於很少使用。相反,人們傾向於「挑選」並從OO中獲得他們需要的特定想法,無論是封裝,繼承,多態等等。

其次有進程。一個進程是一個獨立的封裝實體,你可以發送消息並接收答案。它幾乎與「一個類是一個單獨的封裝實體,你可以使用它來操作它」。由於產生一個進程很便宜,所以將進程作爲面向對象的對象使用並不是問題。

第三種是參數化模塊有些人喜歡使用,就好像它們將OO風格的代碼帶回到該語言中一樣。

四,還有一等功能。由於您可以像數據一樣輕鬆地傳遞函數,因此通常可以使用它來概括代碼而不是構建對象層次結構。


結論:如果你用慣用的風格編寫Erlang,你很少會發現需要相當於'class'。

6

簡短的回答

你不能(至少如果你想認真對待作爲一個Erlang程序員同時具有二郎代碼可以正常工作)。

龍答案

Erlang是一種函數式編程語言,而不是面向對象的編程語言。 「對象」(具有附加功能的狀態集合)的整個基本概念對功能方法(儘可能避開可變狀態)是憎惡的。你可以用一種功能語言來組裝一個類似對象的設置 - 特別是像Erlang這樣的不純的設備 - 但是由此產生的代碼很難閱讀,難以維護,脆弱和醜陋。 (難以閱讀和維護,比寫在OOP語言,甚至面向對象的代碼更脆弱和醜陋的,硬如可能似乎是相信的。)

你會成爲迄今爲止由要麼更好您的需求:

  • 學習表達Erlang原生想法的自然成語和手段(LYSE是此首選解決方案的一個很好的起點);或
  • 使用面向對象的編程語言進行面向對象編程。

在非OOP語言中進行半分類的OOP通常是徒勞且痛苦的。

2

根據你的榜樣,你剛纔叫你qsort與未分類值的適當的列表,並獲得排序列表:

some_useful_fun(X, Y) -> 
    % ... 
    Xsorted = qsort(X), 
    % do something with Xsorted 
    ... 

而這一切。純功能編程中沒有任何狀態。唯一的狀態是作爲參數傳遞給函數的數據。儘管你調用它的次數,函數應該會在傳遞的參數上返回相同的結果。

在Erlang中,您可以將您的對象映射到記錄。考慮以下代碼:

-export([sort/0]). 

-record(person, 
    {  
      name, 
      age 
    }). 

persons_list() -> [ 
      #person{name="John", age=38}, 
      #person{name="Paul", age=25}, 
      #person{name="Michael", age=23} 
    ]. 

qsort(_Pred1, _Pred2, []) -> 
    []; 
qsort(Pred1, Pred2, [Pivot|T]) -> 
    qsort(Pred1, Pred2, [X || X <- T, Pred1(X, Pivot)]) 
    ++ [Pivot] ++ 
    qsort(Pred2, Pred2, [X || X <- T, Pred2(X, Pivot)]). 

sort() -> 
    F1 = fun(#person{age = A1}, #person{age = A2}) -> 
       A1 =< A2 end, 
    F2 = fun(#person{age = A1}, #person{age = A2}) -> 
       A1 > A2 end, 
    qsort(F1, F2, persons_list()). 

我們有一個記錄person,它有兩個領域,特別是nameage。我們還有兩個謂詞F1F2,它們適合於qsort所做的。如果我們現在所說的qsort/3與這兩個謂詞和person記錄列表,我們會得到下面的結果:

1> c(persons). 
{ok,persons} 
2> persons:sort(). 
[{person,"Michael",23}, 
{person,"Paul",25}, 
{person,"John",38}] 
3> 

這是person記錄排序列表後,可以將在代碼中使用。

+0

更多關於Erlang [記錄](http://www.erlang。組織/ DOC/programming_examples/records.html)。 – 2011-02-08 16:20:00

3

Erlang沒有抽象數據類型。定義數據類型的標準方法是通過一個模塊提供數據中的所有訪問功能,並且用戶預期不會繞過它們。 OTP中的這種示例是諸如sets,dictarray之類的東西。這通常運作良好,但你必須知道數據是什麼類型。有時結構已經定義,但用戶在處理數據時應該「表現自己」,例如ordsets

但是請注意,在所有情況下,數據都是標準的不可變Erlang數據,這與大多數傳統OO語言不兼容。我只能重申其他答案中所說的內容,並且不要嘗試像Erlang這樣的非OO語言使用OO風格,反之亦然。結果不會是優雅和美麗。

最後一點:quicksort的定義簡潔明瞭,效率很低。

-2

簡短的回答:

可以。

龍答:

嗯,這是不方便,但。更好的方法是將sort函數傳遞給qsort(如之前提到的Yasir Arsanukaev,與列表中的方式相同:sort/2)。但是「如果你把它放在心上,你可以做任何事情」,正如有人說的那樣。

-module(persons). 

-export([sort_persons/0, sort_sku/0]). 

-record(person, {name, age}). 
-record(sku, {item_number, price}). 

-record(sortable, {lt}). 

-record(object, {state, methods}). 

persons_list() -> 
    Sortable = #sortable{lt=fun(#person{age = A1}, #person{age = A2}) -> A1 < A2 end}, 
    [ 
     #object{state=#person{name="John", age=38}, methods = Sortable}, 
     #object{state=#person{name="Paul", age=25}, methods = Sortable}, 
     #object{state=#person{name="Michael", age=23}, methods = Sortable} 
    ]. 

sku_list() -> 
    Sortable = #sortable{lt=fun(#sku{price = P1}, #sku{price = P2}) -> P1 < P2 end}, 
    [ 
    #object{state=#sku{item_number="11111", price=3.54}, methods = Sortable}, 
    #object{state=#sku{item_number="222222", price=1.58}, methods = Sortable}, 
    #object{state=#sku{item_number="33333", price=2.31}, methods = Sortable}, 
    #object{state=#sku{item_number="44444", price=8.41}, methods = Sortable} 
    ]. 


qsort([]) -> 
    []; 
qsort([Pivot|T]) -> 
    qsort([X || X <- T, (X#object.methods#sortable.lt)(X#object.state, Pivot#object.state)]) 
    ++ [Pivot] ++ 
    qsort([X || X <- T, not (X#object.methods#sortable.lt)(X#object.state, Pivot#object.state)]). 

sort_persons() -> 
    qsort(persons_list()). 
sort_sku() -> 
    qsort(sku_list()). 
相關問題