基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx

上传人:b****5 文档编号:5904266 上传时间:2023-01-02 格式:DOCX 页数:21 大小:61.08KB
下载 相关 举报
基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx_第1页
第1页 / 共21页
基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx_第2页
第2页 / 共21页
基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx_第3页
第3页 / 共21页
基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx_第4页
第4页 / 共21页
基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx_第5页
第5页 / 共21页
点击查看更多>>
下载资源
资源描述

基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx

《基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx》由会员分享,可在线阅读,更多相关《基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx(21页珍藏版)》请在冰豆网上搜索。

基于 JVM 的新一代编程语言 Fantom 来自 IBM带程序示例.docx

基于JVM的新一代编程语言Fantom来自IBM带程序示例

基于JVM的新一代编程语言:

Fantom

陈晨,软件工程师,IBM

王冬蕾,软件工程师,IBM

赵一铂,软件工程师,IBM

简介:

 自从JVM提供非Java语言的支持以来,很多风格迥异的编程语言都加入到JVM的备选语言行列中来。

这其中包括一些“老”编程语言,如JavaScript;也包括一些全新的编程语言,比如Groovy、Scala,以及本文要介绍的Fantom。

 api, java_入门, jvm_(java_virtual_machine), 应用开发, 标准, 算法, 编码

标记本文!

Fantom诞生于2007年,相比于Groovy和Scala来说已经算是比较晚了。

但是它吸收了其他语言的长处,形成了自己独特的语法风格,在新一代基于JVM的语言中占有了重要的地位。

本文是对于Fantom编程语言的一个简要介绍,包括了基本语法和一些高级特性,例如对闭包、动态编程(DynamicProgramming),以及函数式编程(FunctionalProgramming)的支持。

本文的主要目标是使Java开发人员可以熟悉Fantom这种语言,并能感受到Fantom结构上的精简和功能上的强大。

需要注意的是,Fantom并不仅仅可以在JVM中运行,还可以在.netCLR(通用语言运行时)和浏览器中运行。

对多种平台的支持也使得Fantom的竞争力得到了进一步的提升。

安装并配置Fantom

要体验Fantom各种有趣的特性,首先需要在您的计算机上安装Fantom。

在Linux和Windows平台上安装的步骤并不相同,这里介绍Linux平台上的安装方法,Windows平台上则可以参考 这里的教程。

首先在 这里下载Fantom的发行包(zip格式)。

发行包里同时包含了Linux和Windows平台下所需的文件。

下载完成之后,将其解压到您选定的目录。

浏览目录下的内容,您会发现很多Fantom的文档以及示例程序等有用的内容。

当然,最重要的是bin目录下的几个可执行文件,尤其是fan/fan.exe,它是Linux/Windows平台下Fantom语言的解释器和编译器。

接下来需要配置环境变量。

定义一个环境变量FANTOM_HOME(或者任何您喜欢的名字),指向解压Fantom的目录。

然后将FANTOM_HOME/bin添加到PATH中。

最后,运行一下adm目录中的unixsetup,为所有可执行文件添加执行权限:

清单1.为Fantom的可执行文件添加权限

bashadm/unixsetup

至此,Fantom的运行环境就配置完毕了。

或许您还希望安装一个集成开发环境(IDE)。

目前支持Fantom的IDE还不是很多,推荐使用基于Eclipse的 FantomIDE。

不过由于Fantom语言的简洁性,使用普通的文本编辑器也一样可以很好的完成开发工作。

接下来,像所有编程语言的介绍一样,我们从“HelloWorld”开始。

不同版本的HelloWorld

使用Fantom解释器

Fantom从本质上来说是一种脚本语言,所以您可以写出如下简洁的HelloWorld脚本:

清单2.Fantom的HelloWorld脚本

classHelloWorld

{

staticVoidmain()

{

echo("Helloworld!

")

}

}

保存为helloworld.fan,然后这样运行它:

清单3.运行HelloWorld脚本

root@computer:

~#fanhelloworld.fan

Helloworld!

直接在Shell中运行

和很多脚本语言一样,Fantom也提供了一个Shell环境。

您同样可以在Shell环境中完成HelloWorld:

清单4.Shell环境中的HelloWorld

root@computer:

~#fansh

FantomShellv1.0.56(‘?

’forhelp)

fansh>echo(“Helloworld!

”)

Helloworld!

fansh>quit

Web应用程序中的HelloWorld

作为JVM的备选语言之一,Java做到的Fantom也能做到。

所以我们也可以把HelloWorld显示到Web页面上。

Fantom中提供了对Web服务器的内置支持(WISP库)。

所以我们不需要第三方的Web服务器就可以实现一个简单的Web应用程序。

下面是Fantom发行包里面附带的一个例子,您可以在example/web/hello.fan中找到:

清单5.Web环境中的HelloWorld

usingutil

usingweb

usingwisp

classWebHello:

AbstractMain

{

@Opt{help="httpport"}

Intport:

=8080

overrideIntrun()

{

wisp:

=WispService

{

it.port=this.port

it.root=HelloMod()

}

returnrunServices([wisp])

}

}

constclassHelloMod:

WebMod

{

overrideVoidonGet()

{

res.headers["Content-Type"]="text/plain;charset=utf-8"

res.out.print("helloworld#4")

}

}

下面对这段代码做一些说明:

∙类WebHello继承自AbstractMain,AbstractMain用于快速地创建应用程序,无论是Web应用程序,还是桌面应用程序,都可以通过继承这个类来方便的创建。

WebHello重载了AbstractMain中的run方法,这个方法是应用程序的入口点,这里用来初始化Web服务器;

∙run方法中声明了一个WispService的实例,这个实例中指定Web服务器的端口(8080)和开启的服务(HelloMod);

∙HelloMod类相当于Java中的Servlet,其中有一个重载的onGet方法,相当于Servlet中的doGet。

在这个例子的onGet方法中,除了指定HTTP头以外,只输出了一行“helloworld#4”。

由于Fantom提供了内置的Web服务器支持,运行这个例子十分简单,只需要使用Fantom解释器处理这段代码:

清单6.运行HelloWorld

root@computer:

~#fanexamples/web/hello.fan

[16:

08:

5721-Dec-10][info][web]WispServicestartedonport8080

看到上面所示的WISP服务启动成功的信息之后,您就可以在浏览器中访问 http:

//localhost:

8080来查看运行结果了,十分方便,是不是?

上面介绍了三种不同形式的使用Fantom语言编写的HelloWorld程序。

仔细观察这些代码,您会发现Fantom的语法和Java有很大的不同。

正是这种独特的语法使Fantom语言的代码十分简洁易懂。

兼容并包的语法

Fantom在语法上有很多和Java相同的地方,包括绝大部分的运算符,if…else结构,while和for循环等。

但做为一种新的编程语言,Fantom也吸收了很多其他编程语言的语法特性。

接下来会举例介绍。

语句

Fantom的语句是以行为单位的,语句的结尾并不需要分号,这一点与Java不同。

但为了照顾众多Java和C++程序员的使用习惯,以分号分隔的语句也同样被支持:

清单7.Fantom的语句

if(true){

dosomething()

return

}//OKforFantom

if(true){

dosomething();

return;

}//OKforFantom

if(true){

dosomething();return;

}//OKforFantomtoo

声明与赋值

对于像Java和C++这样的强类型编程语言来说,声明和赋值语句看起来没什么区别,除了声明语句最左侧的类型定义:

清单8.Java的声明和赋值语句

Stringfoo=“Foo”;//Javadeclaration

foo=“Foo”;//Javaassignment

而对于弱类型的语言,例如Perl来说,声明和赋值语句看起来是完全一样的。

这使得有的时候代码十分难于读懂:

清单9.Perl的声明和赋值语句

$foo=“Foo”;//Perlassignmentordeclaration

而Fantom同时支持强类型和弱类型风格的变量声明:

清单10.Fantom的声明语句

Strfoo:

=“Foo”

foo:

=“Foo”

而赋值语句是这样的:

清单11.Fantom的赋值语句

foo=“Foo”

可以看到声明和赋值时使用的操作符是不一样的。

这使得代码更加清晰易读。

空对象安全的成员引用操作符

在使用Java开发应用程序的时候,一个特别需要注意的地方就是避免对空对象使用成员引用操作符(.),如果对一个为null的对象使用成员引用操作符,会抛出NullPointerException异常。

但在Fantom中,如果您使用像下面这样的空对象安全的(Null-Safe)代码,就可以无需考虑这个问题:

清单12.空对象安全的成员引用

price=fruitMap?

.find(“Apple”)?

.getPrice()

这行代码相当于:

清单13.与清单12等价的代码

Intprice:

=null

if(fruitMap!

=null)

{

fruit:

=fruitMap.find(“Apple”)

if(fruit!

=null)

price=fruit.getPrice()

}

可见如果fruitMap或者fruitMap.find()的返回值为null,则price也为null。

在这个过程中并不会抛出任何异常,而且只需要一条语句,十分简洁。

列表和映射

Fantom中借鉴了Perl的数据类型——列表(List)和映射(Map,Perl中称之为散列——Hash)。

而在Java中实现同样的数据结构则需要使用接口java.util.List和java.util.Map的实现类,很显然Fantom中选用了更简洁的语法。

下面举例说明:

清单14.Fantom的列表

Int[10,20,30]

[10,20,30]

上面两条语句的效果是一样的,在列表中的元素类型已经确定的情况下,前面的数据类型定义可以省略。

Fantom还引入了一种新的数据类型表示,即在数据类型后面加?

,这种新的数据类型的默认值为null,而不是根据类型不同而使用不同的默认值,例如Int,预设的默认值是0,而Int?

的默认值是null。

默认的Int列表是不能够储存null类型的元素的,如果想要实现这一点,需要如下的定义:

清单15.能储存null元素的列表

[10,null,30]

Int?

[10,20,30]

第一条语句中的第二个元素是null,因此列表被定义为Int?

类型,而第二条语句则是显式指定列表为Int?

类型,两条语句的效果是一样的。

上面的例子中我们可以知道,Fantom对于元素类型不统一的列表定义,会为列表使用一个通用的数据类型,下面是几个例子:

清单16.不同类型元素的混合列表

[10,”20”,30]//evaluatestoObj[]

[10,20f,30]//evaluatestoNum[]

对于[10,“20”,30]这个例子,由于第二个元素是Str类型,而另外两个元素是Int类型,因此这个列表的类型是Int和Str的共同基类——Obj。

第二个例子同理,列表的类型是Int和Float的共同基类——Num。

映射用来储存一组键/值对,定义映射的语句如下:

清单17.Fantom的映射

[Int:

Str][1:

”one”,2:

”two”,3:

”three”]

Int:

Str[1:

”one”,2:

”two”,3:

”three”]

[1:

”one”,2:

”two”,3:

”three”]

上面三种定义是等价的。

映射在其元素数据类型不一致时的规则与列表相同,不再赘述。

上述的只是一些Fantom的一些新的语法特点,更详细的介绍可以在Fantom的在线文档库中找到。

简洁优雅的类和容器

类的定义

在了解Fantom的基本语法之后,下面来介绍Fantom中类的定义。

对于Java语言来说,JavaBean是一个很重要的概念,一个典型的JavaBean定义里,通常有若干个private的成员变量,以及用来存取这些成员变量的public的getter和setter方法,另外可能还有一些其他的public方法,如下面的例子:

清单18.Java的类定义

publicclassEmployee{

privateStringname;

privateIntegerage;

privateIntegeryearOfService;

publicStringname(){returnthis.name;}

publicvoidname(Stringname){this.name=name;}

publicIntegerage(){returnthis.age;}

publicvoidage(Integerage){this.age=age;}

publicIntegeryearOfService(){returnthis.yearOfService;}

publicvoidyearOfService(IntegeryearOfService)\

{this.yearOfService=yearOfService}

publicFloatcalculateSalary(){……}

}

而在Fantom中,对应的类只需要很少的代码:

清单19.Fantom的类定义

classEmployee{

Strname

Intage

IntyearOfService

FloatcalculateSalary(){……}

}

Fantom会自动生成对应的getter和setter方法。

如果需要自己重载,也相当简单:

清单20.重载setter方法

classEmployee{

Strname

Intage{set{checkAge(val);&age=it}}

IntyearOfService

FloatcalculateSalary(){……}

}

其中的 it是保留字,表示将要赋给成员变量的值,即setter方法的参数;&age表示成员变量age实际的存储单元。

事实上,Fantom还自动生成了一个类的默认构造函数,这个构造函数以保留字 make为名字:

清单21.类的构造函数

classEmployee{

Strname

Intage

IntyearOfService

newmake(Strname,Intage,IntyearOfService)

{

this.name=name

this.age=age

this.yearOfService=yearOfService

}

}

在Java中,类的构造函数是没有返回类型的,而在Fantom中,构造函数前需要加保留字 new以示不同。

Fantom中的容器

在Java语言中,代码的管理是以包(package)为单位的。

包定义了一个名字空间(namespace),使得在代码量较大的时候管理起来比较容易,同时也使得不同名字空间下的代码相互隔离。

包的名称是层次化的,整个代码库是一个树状结构:

图1.Java的代码结构

 

包的引入解决了名字混乱的问题,但是如果包的层次比较多的话,整个代码结构仍然会变得难以读懂。

而在Fantom中,包的概念被容器(Pod)所代替,代码被组织为两个层次:

容器和类。

于是代码呈现一种扁平的两层结构:

图2.Fantom的代码结构

 

实际上Fantom中的容器不仅能完成代码管理的工作,还能提供代码部署时的支持,在这点上,它相当于Java中的Jar文件,或者.NET平台上的DLL文件。

我们可以把之前的HelloWorld程序包装进容器中,虽然对于这种规模很小的程序没有什么用处,但是可以通过这个过程了解Fantom下容器的概念,以及打包代码库的方法。

这里以Linux环境下为例。

首先我们需要设置容器的目录结构,选择一个目录作为容器的工作目录,过一会儿我们要在这个目录下放置编译脚本。

再选择一个目录作为代码目录,放置待编译的代码,为了方便,我们把代码目录放在工作目录下,结构如下所示:

清单22.目录结构

hello/

build.fan

source/

hello.fan

这里的build.fan就是编译脚本,实际上它也是以Fantom源代码形式编写的,内容如下:

清单23.编译脚本

classBuild:

build:

:

BuildPod

{

newmake()

{

podName="hello"

summary="helloworldpod"

depends=["sys1.0"]

srcDirs=[`source/`]

}

}

我们可以看到,这个编译脚本实际上创建了一个BuildPod的派生类,并在构造函数中设置了必要的一些参数。

容器build中提供了很多用于编译Fantom代码库的功能,读者们可以参考Fantom的文档库查询详细的介绍。

对于HelloWorld程序来说,我们只需要一个源代码文件hello.fan,它的内容如下:

清单.24HelloWorld代码

classMain

{

staticVoidmain(){echo("Helloworld!

")}

}

由于编译脚本实际上也是Fantom源代码,我们只需要使用Fantom解释器运行这段脚本就能完成编译:

清单25.编译HelloWorld容器

root@computer:

~/hello#fanbuild.fan

compile[hello]

Compile[hello]

FindSourceFiles[1files]

WritePod[file:

/usr/local/fantom/lib/fan/hello.pod]

BUILDSUCCESS[39ms]!

代码已经编译完成了,我们可以在命令行中访问容器里的方法:

清单26.在Shell中访问容器中的方法

root@computer:

~/hello#fanhello

Helloworld!

root@computer:

~/hello#fanhello:

:

Main

Helloworld!

root@computer:

~/hello#fanhello:

:

Main.main

Helloworld!

同样也可以在代码里访问容器里的方法。

创建一个新的文件AccessPod.fan,加入如下代码:

清单27.在代码里访问容器中的方法

usinghello

classAccessPod{

staticVoidmain(){hello:

:

Main.main()}

}

root@computer:

~#fanAccessPod.fan

Helloworld!

在前面的例子中我们可以看到,编译Fantom源代码得到的是.pod文件,这种文件中包含了编译Fantom源代码而生成的字节码(我们称之为Fcode)、常量池以及程序运行必须的资源文件等。

实际上它是一个普通的zip文件,您可以使用任何解压缩工具来查看其中的内容:

清单28.解压pod文件

root@computer:

~/fantom/lib/fan#unzip./hello.pod–d./hello

Archive:

./hello.pod

inflating:

./hello/meta.props

inflating:

./hello/fcode/names.def

inflating:

./hello/fcode/typeRefs.def

inflating:

./hello/fcode/methodRefs.def

inflating:

./hello/fcode/strs.def

inflating:

./hello/fcode

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 求职职场 > 简历

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1