Java开发人员的Erlang

您可能没有注意到,但是距离我上次发布博客已经过去了几个星期。 原因是我的Soleus骨折了,而我的腿也石膏了。 不能动弹,我认为调查完全不同的东西是个好主意–要么看那天的电视,要么,尽管Kojak和Magnum PI的重播很诱人,但对Erlang的调查却名列前茅。

这里要记住的是,这不是
Erlang教程 ,这里的想法是研究Erlang和Java之间的一些相似之处,以尝试为学习Erlang提供一个起点。 如果我犯了任何啸叫错误,那么希望有更多Erlang经验的人会告诉我。 erlang徽标 入门时,他们首先告诉您有关Erlang的信息,它是一种功能语言。 但是,在您陷入中风之前,它是一种结构良好的功能语言,以为您正在处理对象。

那是什么意思 在Java中,代码存储在表示类的文件中,类是执行单一职责的一组数据和方法。 您可以实例化一个类并通过变量访问其方法,也可以通过其类名访问其静态方法。

在Erlang中,代码存储在称为模块的文件中,每个模块都是执行一项职责的一组功能。 您无法实例化模块,并且实例变量和类变量不存在。 您只能使用方法参数变量。 您可以通过其模块名称来访问方法,就像访问Java静态方法一样。 与Java类一样,Erlang模块具有私有和公共功能。 Java徽标

作为Java开发人员,我很高兴发现有一个
eclipse的Erlang插件 。 这是因为学习一种语言而不是一种语言和一套全新的开发工具会更快。 几个月前,我与几位Erlang顾问进行了交谈,他们说他们更喜欢使用emacs,而我确实想知道为什么要等到我发现eclipse插件才算不错。 仍然足以开始使用,并且它具有潜力。

Java开发人员应该有其他相似之处:Erlang模块源文件被编译成.beam文件,然后在Erlang虚拟机上运行; 还有eunit ,Erlang相当于JUnit ,还有一个log4erl ,顾名思义,是Erlang的Log4J版本。 使用edoc (Erlang的Javadoc版本)和标准项目布局可以自动生成文档,这与Maven布局非常相似,如下所示:
屏幕截图2013年7月29日在18.39.29
其结构与Maven略有不同: 目标目录称为ebin ,并且srctest目录已在项目目录级别进行了拆分,但是易于遵循,您已习惯了。

到目前为止,您已经认为Java和Erlang之间的最大区别是Java文件具有.java扩展名,而Erlang文件具有.erl扩展名。 不幸的是,还有更多的东西,首先是没什么大不了的,或者是Erlang看起来很奇怪的语法1

为了对此进行调查,我认为我将使用现有的ShoppingCartShoppingCartTest类并将其转换为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 。

参考:来自Captain Debug博客博客的JCG合作伙伴 Roger Hughes的Java开发人员Erlang 。

翻译自: https://www.javacodegeeks.com/2013/08/erlang-for-java-developers.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/367415.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20165339第六周学习总结

课本知识点总结 第八章 String类 使用String类声明对象并创建对象 String s new String("We are students"); String t new String("We are students"); String (char a[])用一个字符数组a创建一个String对象 char a[] {J,a,v,a}; String s new String(a)…

keil5用jlink不到芯片_洛达芯片检测

安卓手机下载一个络达官方的刷机软件然后连接上耳机&#xff0c;打开软件&#xff0c;就可以看到耳机芯片的相关信息。软件下载地址&#xff1a;https://pan.baidu.com/s/1MOXjkHv1wfxWWIVdcsMSFg 提取码: tasc我们的耳机都是络达芯片&#xff0c;不怕你检测&#xff0c;希望用…

层次和约束:项目中使用vuex的3条优化方案

问题描述 使用vuex的store的过程中&#xff0c;发现了一些不是很优雅的地方&#xff1a; store层module太多&#xff0c;找state、getter、mutation、action对应的module比较慢。 组件里面mapGetters、mapActions、mapMutations过多&#xff0c;分不清getter、action、mutati…

怎么让员工服从管理_为什么现在的员工执行力和服从性越来越差,管理一严格就辞职?...

当有负面情绪的时候&#xff0c;不要说。管好自己的嘴&#xff0c;有时候做哑巴&#xff0c;是一种境界。现在的企业很多都存在这个问题&#xff0c;员工执行力越来越差&#xff0c;服从性也越来越差&#xff0c;管理者稍微一严格&#xff0c;员工就会辞职走人&#xff0c;留不…

Spring Data REST的实际应用

什么是春天数据休息&#xff1f; spring-data-rest是spring-data项目的新增功能&#xff0c;它是一个框架&#xff0c;可帮助您将实体直接作为RESTful Web服务端点公开。 与rails&#xff0c;grails或roo不同&#xff0c;它不会生成任何实现此目标的代码。 spring data-rest支持…

2018上半年掘金微信群日报优质文章合集:前端篇

在掘金微信交流群里的小伙伴们&#xff0c;你们每天都还在坚持读小报吗&#xff1f;如果你的回答是yes&#xff0c;那真的要给你点一万个赞了?能坚持这么久&#xff0c;真的很优秀噢&#xff01;&#xff08;嗯&#xff0c;每天坚持给大家收集文章的小饼也很优秀?&#xff09…

linux运维笔试题目,linux运维相关的笔试题目_笔试题目

一、Linux系统和shell1、写一个sed命令&#xff0c;修改/tmp/input.txt文件的内容&#xff0c;要求&#xff1a;①删除所有空行&#xff1b;②在非空行前面加一个“AAA”&#xff0c;在行尾加一个“BBB”&#xff0c;即将内容为“11111”的一行改为&#xff1a;“AAA11111BBB”…

python之路--day17-shelve,xml和re模块

shelve模块 shelve模块只有一个open函数&#xff0c;返回类似字典的对象&#xff0c;可读可写&#xff0c;key必须为字符串&#xff0c;而值可以是python所支持的数据类型 1 import shelve2 # info1{age:18,height:180,weight:80}3 # info2{age:73,height:150,weight:80}4 #5 #…

20172314 2018-2019-1《程序设计与数据结构》第一周学习总结

教材学习内容总结 概述 软件工程&#xff1a;是一门关于高质量软件开发的技术和理论的学科&#xff0c;用来控制开发过程&#xff0c;实现高质量的软件。软件工程的目标&#xff1a;正确性、可靠性、健壮性、可用性、可维护性、可重用性、可移植性、运行效率。 对于可靠性和健壮…

activiti api文档_【白银人机】Activiti 工作流从入门到入土:完整 hello world 大比拼(API 结合实例讲解)...

点击上方“好好学java”&#xff0c;选择“置顶”公众号重磅资源、干货&#xff0c;第一时间送达重磅推荐 ① 纯福利 | 公众号资源大汇总&#xff0c;一年才一次&#xff01;② 重磅&#xff01;&#xff01;2018年Java全套入门到进阶学习视频及项目实战③ 2018年java架构师学习…

前端解读控制反转(IOC)

前言 随着前端承担的职责越来越重&#xff0c;前端应用向着复杂化、规模化的方向发展。大型项目模块化是一种趋势&#xff0c;不可避免模块之间要相互依赖&#xff0c;此外还有很多第三方包。这样的话如何去管理这些繁杂的文件&#xff0c;是一个不可避免的话题。此时作为一种…

ASP.NET MVC传递参数(model), 如何保持TempData的持久性

一看到此标题&#xff0c;相信你也会。因为路由是可以从URL地址栏传过去的。但是Insus.NET不想在地址栏传递&#xff0c;还是一个条件是jQuery的Ajax进行POST的。Insus.NET不清楚别人是怎样处理的&#xff0c;但是这个让Insus.NET花上不少时间来解决。Insus.NET实现的方法也很简…

深度学习语音降噪方法对比_人工智能-关于深度学习的基础方法

深度学习概述深度学习的一些简介&#xff0c;其要点如下&#xff1a;深度学习实际上是基于具有多个隐藏层的神经网络的学习&#xff1b;深度学习的思想来源于人类处理视觉信息的方式&#xff1b;深度学习的发展得益于数据的井喷和计算力的飙升&#xff1b;深度学习的理论基础依…

通过adb巧用monkey获取android设备中所有应用的主activity

由于工作需要&#xff0c;想获取所有应用的activity(这里仅限应用的主入口Launcher activity)&#xff0c;搜索了一下&#xff0c;网上实现的方案都是基于android编程实现的&#xff0c;对于不懂开发的测试来说稍有难度&#xff0c;而且对于PC端测试工具来说可行性略差。 给大家…

PWA · 前后端协作 · Node | JTalk 掘金线下活动第七期

通知 余票仅剩 3张&#xff0c;欢迎加入活动群获取更多通知。北京的小伙伴可以关注我们的 JTalk 第八期&#xff1a;前端安全 | 美团点评技术团队专场 ? 报名 扫码报名&#xff1a; 报名链接&#xff1a;点我报名 ? 介绍 本期 JTalk 来杭州啦&#xff01; 掘金线下活动 J…

指数函数中x的取值范围_基本初等函数I: 指数函数、对数函数和幂函数

本文大约4800字, 建议学习时间1个小时.在学习过一次函数和二次函数(修改版)后, 我们知道, 一次函数ykxb当一次项系数k大于零时是增函数, 小于零时是减函数. 二次函数yax2bxc当二次项系数a大于零时图象沿x轴从左向右先减后增, a小于零时先增后减. 可以想象, 次数更高的函数, 在定…

Linux系统之TroubleShooting(启动故障排除)

尽管Linux系统非常强大&#xff0c;稳定&#xff0c;但是我们在使用过程当中&#xff0c;如果人为操作不当&#xff0c;仍然会影响系统&#xff0c;甚至可能使得系统无法开机&#xff0c;无法运行服务等等各种问题。那么这篇博文就总结一下一些常见的故障排除方法&#xff0c;但…

皮肤可配置化:变量、样式分离

之前皮肤开发了一个版本&#xff0c;抽是抽出来了&#xff0c;但是变量只抽出了几个颜色&#xff0c;没什么价值&#xff08;上个版本开发过程&#xff09;&#xff0c; 这次我又进行了一次迭代&#xff0c;现在是一个较成熟的版本了。整体理一下思路&#xff0c;可以总结为3步…

【考试记录】4.8 Path (网络流 —— 劲题)

手抄代码 学习指针 冥思苦想一晚上终于——在一瞬间开窍了。果然题目都是这样&#xff1a;突破了一个点&#xff0c;一切都是柳暗花明。 题面描述&#xff1a; 样例&#xff1a; 这道题目&#xff0c;首先注意到给定的边的性质&#xff1a;这些边在平面上构成了一棵树&#x…

Servlet 3.0概述

Servlet 3.0 –具有许多突破性的功能&#xff0c;这些功能最终将改变开发人员编写和编写JEE Web应用程序的方式–有人可能会说&#xff0c;它的约定违背了我们对事物在理论上“应该”如何工作的大多数理解&#xff0c;但这就是其中之一。创新和持续改进&#xff1b; 挑战公约并…