java erlang_Java开发人员的Erlang
java erlang
您可能沒有注意到,但是距離我上次發布博客已經過去了幾個星期。 這是由于我的Soleus骨折了,而且我的腿是石膏模型。 不能動彈,我認為調查完全不同的東西是個好主意–要么看那一天,要么看白天的電視,盡管Kojak和Magnum PI的重播很誘人,但對Erlang的調查卻排在首位。
 這里要記住的是,這不是一個 
 Erlang教程 ,這里的想法是檢查Erlang和Java之間的一些相似之處,以嘗試提供學習Erlang的起點。 如果我犯了任何嘯叫錯誤,那么希望有更多Erlang經驗的人會告訴我。 
  入門時,他們首先告訴您有關Erlang的信息,這是一種功能語言。 但是,在您陷入困境之前,它是一種結構良好的功能語言,以為您正在處理對象。 
那是什么意思 在Java中,代碼存儲在表示類的文件中,類是執行單一職責的一組數據和方法。 您可以實例化一個類并通過變量訪問其方法,也可以通過其類名訪問其靜態方法。
在Erlang中,代碼存儲在稱為模塊的文件中,每個模塊都是執行一項職責的一組功能。 您無法實例化模塊,并且實例變量和類變量不存在。 您只能使用方法參數變量。 您可以通過其模塊名稱來訪問方法,就像訪問Java靜態方法一樣。 與Java類一樣,Erlang模塊具有私有和公共功能。
 作為Java開發人員,我很高興發現有一個 
 eclipse的Erlang插件 。 這是因為學習一種語言而不是一種語言和一套全新的開發工具會更快。 幾個月前,我與幾位Erlang顧問進行了交談,他們說他們更喜歡使用emacs,而我確實想知道為什么要等到我發現eclipse插件才算不錯。 仍然足以開始使用,并且它具有潛力。 
 Java開發人員應該有其他相似之處:Erlang模塊源文件被編譯為.beam文件,然后在Erlang虛擬機上運行; 還有eunit ,它是Erlang的等效于JUnit ,還有一個log4erl ,顧名思義,是Erlang的Log4J版本。 使用edoc (Erlang的Javadoc版本)和標準項目布局可以自動生成文檔,這與Maven布局非常相似,如下所示: 
  
 其結構與Maven略有不同: 目標目錄稱為ebin ,并且src和test目錄已在項目目錄級別進行了拆分,但是易于遵循并且您已習慣了。 
根據到目前為止的內容,您會認為Java和Erlang之間的最大區別是Java文件具有.java擴展名,而Erlang文件具有.erl擴展名。 不幸的是,還有更多的東西,首先是沒什么大不了的,或者是Erlang看起來很奇怪的語法1 。
為了對此進行調查,我認為我將使用現有的ShoppingCart和ShoppingCartTest類并將其轉換為Erlang。 我的telldontask項目中提供了這兩個類,它們看起來像這樣……
ShoppingCart類
public class ShoppingCart { private final List<Item> items; private PaymentMethod method; public ShoppingCart() { items = new ArrayList<Item>(); } public void addItem(Item item) { items.add(item); } public double calcTotalCost() { double total = 0.0; for (Item item : items) { total += item.getPrice(); } return total; } public double calcTotalCost(double shipping, double minShippingAmount) { double totalCost = calcTotalCost(); if (totalCost > minShippingAmount) { totalCost += shipping; } return totalCost; } public void setPaymentMethod(PaymentMethod method) { this.method = method; } public void pay(double shipping, double minShippingAmount) { double totalCost = calcTotalCost(shipping, minShippingAmount); method.pay(totalCost); } }ShoppingCartTest JUnit
public class ShoppingCartTest { /** * Test method for {@link tell_dont_ask.ask.ShoppingCart#getAllItems()}. */ @Test public void calculateTotalCost() { ShoppingCart instance = new ShoppingCart(); Item a = new Item("gloves", 23.43); instance.addItem(a); Item b = new Item("hat", 10.99); instance.addItem(b); Item c = new Item("scarf", 5.99); instance.addItem(c); double totalCost = instance.calcTotalCost(); assertEquals(40.41, totalCost, 0.0001); } }上面的代碼演示了一些非常基本的購物車功能; 但是,有關這些類如何工作的更多詳細信息,請參閱“ 定義告訴不要問”和“ 分解告訴不要問” 。
Erlang中的等效代碼如下所示:
shopping_cart模塊
-module(shopping_cart). %% ==================================================================== %% API functions %% ==================================================================== -export([add_item/2,calc_total_cost/1,calc_total_cost/3,pay/3]). %% @doc Add an item to the order list add_item(OrderList,Item) -> [Item | OrderList]. %% @doc Calculate the total cost of all the items in a list. The List must have the following format: %%? [{itemName, Price}] %%? where %%? itemName -> atom %%? Price -> float() calc_total_cost(OrderList) -> round_dp(calc_total_cost(0,OrderList)). %% @doc Calculate the total cost of all the items in a list adding a shipping cost if the value is below a certain limit. %% The Order List must have the following format: %%? [{itemName, Price}] %%? where %%? itemName -> atom %%? Price -> float() calc_total_cost(OrderList,Shipping, MinShippingAmount) -> Cost = calc_total_cost(OrderList), TotalCost = Cost + shipping(Cost,Shipping,MinShippingAmount), round_dp(TotalCost). %% @doc @todo Method not implemented pay(_Order,_Shipping, _MinShippingAmount) -> unimplemented. %% ==================================================================== %% Internal functions %% ==================================================================== calc_total_cost(Result,[{_,Price} | TheRest]) -> calc_total_cost(Result + Price,TheRest); calc_total_cost(Result,[]) -> Result. shipping(Cost,Shipping,MinShippingAmount) when Cost < MinShippingAmount -> Shipping; shipping(_,_,_) -> 0. round_dp(Number) -> List = float_to_list(Number,[{decimals,2}]), list_to_float(List).shopping_cart_tests模塊
-include_lib("eunit/include/eunit.hrl"). -module(shopping_cart_tests). %% ==================================================================== %% API functions %% ==================================================================== -export([]). %% @doc Calculate total code - written to match the Java style calculate_total_cost_test() -> EmptyList = [], OrderList1 = shopping_cart:add_item(EmptyList,{gloves,23.43}), OrderList2 = shopping_cart:add_item(OrderList1,{hat,10.99}), OrderList3 = shopping_cart:add_item(OrderList2,{scarf,5.99}), ?_assertEqual(40.42,shopping_cart:calc_total_cost(OrderList3)). %% @doc Calculate total cost example - written in a better erlang style calculate_total_cost_2_test() -> OrderList = [{gloves,23.43},{hat,10.99},{scarf,5.99}], ?assertEqual(40.41,shopping_cart:calc_total_cost(OrderList)).專家告訴我,使用Erlang可以用更少的代碼行做更多的事情。 這里不是這種情況,但是我又添加了很多注釋行(用'%'分隔符表示)。
與Java相比,上面的代碼看起來很怪異(因為我沒有從Erlang到HTML的轉換器,所以看上去也有些丑陋)。 沒有任何實例變量,因此所需的任何數據都作為函數參數傳入。 如果看一下add_item(…)您會發現它將Item變量添加到列表的開頭,例如: items.add(item) (請注意,在Erlang中,變量名始終以大寫字母開頭)。
轉到calc_total_cost() ,事情開始看起來真的很奇怪…… calc_total_cost(OrderList)只是calc_total_cost(0,OrderList)的包裝。 calc_total_cost(0,OrderList)是對calc_total_cost(Result,[{_,Price} | TheRest])或calc_total_cost(Result,[])的調用,它們是循環執行從列表中添加商品價格的函數。 除非它不循環; Erlang中沒有for循環,您必須使用遞歸,在calc_total_cost(Result,[{_,Price} | TheRest])逐步添加價格,然后遞歸調用自身,直到列表為空。
關于Erlang語法的問題是,盡管對于使用C派生語言的Java開發人員來說,它是非常合乎邏輯的,因此很容易上手。
要注意的一件事是,上面的Erlang是模仿Java編寫的。 這可能不是您從頭開始開發Erlang購物車的方式。
為什么選擇Java而不是Erlang? 當然不是因為它與Java相似。 當Java的功能和優點可以幫助您更有效,更經濟地解決問題時,您會選擇Erlang而不是Java。 根據Lenart?hman的Google Tech Talk Erlang的目標應用程序,這些應用程序必須是:
- 容錯
 - 馬不停蹄
 - 同時
 - 分布,可擴展和異構
 - 軟實時
 - 需要“原型性”
 
這些目標已經以多種方式實現。 例如,進程之間傳遞的消息是語言的一部分,而不是單獨的API。 要將消息發送到另一個進程,只需鍵入:
Pid ! theMessage,…其中Pid是將接收theMessage的進程的ID。 要發送消息,請輸入在另一個Erlang虛擬機上運行的另一個進程:
Pid ! theMessage,從這個不愉快的笑話中,我可能已經猜到Erlang虛擬機上的進程是透明的。 這意味著它與運行它們的機器上的Erlang進程沒有什么不同。 無論是在本地還是在不同的物理硬件上。 這是因為Erlang虛擬機可以互相通信并且可以集群。 JVM之外的某種方式。
要接收消息,請使用Erlang關鍵字: receive ,如下所示:
%% @doc Receive a message and print the contents print() -> receive Message -> io:format("The message is: ~p~n",[Message]) end.進程本身非常輕巧,旨在以其他語言無法模仿的方式在大型多核處理器上利用超線程。 流程在Erlang中非常重要,我在某處讀到,如果Java是一種面向對象的語言,那么Erlang就是一種面向過程的語言。
如果此博客的內容像是Erlang的廣告,那是因為在將腳趾浸入水中之后,我可以看到它比基于Java的解決方案更經濟,更省力地解決了許多問題。 另一方面,還有Java和Spring(此博客的常見主題)更適合的那些問題。 計算機語言只是簡單的工具,您應該選擇適合自己的最佳語言。
 1奇怪的是,您是否基于Prolog而不是C而成為Java程序員。 
 可從Captain Debug Github存儲庫中獲得此??博客的Java代碼示例: 
 https://github.com/roghughe/captaindebug ,而Erlang代碼可從我的Erlang Samples Github存儲庫中獲得: https://github.com/roghughe/erlang_samples 。 
翻譯自: https://www.javacodegeeks.com/2013/08/erlang-for-java-developers.html
java erlang
總結
以上是生活随笔為你收集整理的java erlang_Java开发人员的Erlang的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: ddos攻击需要什么条件(ddos攻击需
 - 下一篇: 在Docker容器中的Tomcat上运行