精华帖 (0) :: 良好帖 (1) :: 新手帖 (11) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2009-10-15
最后修改:2009-10-15
Andrew Hunt和David Thomas在他们的书The Pragmatic Programmer中建议说:每个程序员每年至少应该学习一门新的语言.
参考资料: Programming Scala - Tackle Multi-Core Complexity on the Java Virtual Machine Programming Scala(Animal Guide) Programming in Scala: A Comprehensive Step-by-step Guide
先来看看最简单的Hello World程序在Scala中长什么样: object Hello { def main(args: Array[String]) = println("Hello Scala!") }
把上面这几行scala代码保存到一个文件中,随便起个名字(比如hello.scala),然后打开一个命令行窗口,将当前路径切换到hello.scala文件所在的目录, scalac Hello.scala
要执行这个程序的话,只要运行: scala Hello
首先来学习一些最简单的Scala语言知识以便理解这个简单Scala程序
那么这段代码到底是如何工作的呢?让我们先看看scalac为我们生成的class文件,在hello.scala文件所在的目录可以看到,scalac编译出了两个class文件:Hello.class和Hello$.class,用JAD反编译一下看看.
Hello.class : import java.rmi.RemoteException; public final class Hello { public static final void main(String args[]) { Hello$.MODULE$.main(args); } public static final int $tag() throws RemoteException { return Hello$.MODULE$.$tag(); } }
Hello$.class : import java.rmi.RemoteException; import scala.Predef$; import scala.ScalaObject; public final class Hello$ implements ScalaObject { public Hello$() { } public void main(String args[]) { Predef$.MODULE$.println("Hello Scala!"); } public int $tag() throws RemoteException { return scala.ScalaObject.class.$tag(this); } public static final Hello$ MODULE$ = this; static { new Hello$(); } }
其中好像有些RMI相关的代码,暂时与我们的讨论无关,我把它们先去掉. 另外,Hello$.class的MODULE$ 初始化好像有点问题,我猜是JAD的问题,我把它们修正如下:
Hello.class : public final class Hello { public static final void main(String args[]) { Hello$.MODULE$.main(args); } }
Hello$.class : import scala.Predef$; import scala.ScalaObject; public final class Hello$ implements ScalaObject { public Hello$() {} public void main(String args[]) { Predef$.MODULE$.println("Hello Scala!"); } public static final Hello$ MODULE$ = new Hello$(); }
结论已经很明显了:
声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2009-10-15
lz 请到 helloworld 达人圈子报到
|
|
返回顶楼 | |
发表时间:2009-10-16
顶NS,helloworld 达人圈子欢迎楼主~
话说Scala的return跟Ruby的确实像,都能做non-local return: 先定义foo函数: def foo(i: Int): Int = { val bar = (j: Int) => { return j + 1 } bar(i) println("foo(" + i + ") end") i } 然后调用它: foo(3) 发现就得到了返回值是4而已,那句println()显然也没执行。这就是non-local return... |
|
返回顶楼 | |
发表时间:2009-10-16
哈哈,被你们两个抢先啦,我也来凑个热闹。支持一下楼主,欢迎到Scala圈子来看看。
@RednaxelaFx:你的代码很有趣,的确像你说的一样。为什么返回不是i的3呢,可否简单说明一下何为non-local return。 |
|
返回顶楼 | |
发表时间:2009-10-16
最后修改:2009-10-16
def foo(i: Int): Int = { val bar = (j: Int) => { return j + 1 } bar(i) println("foo(" + i + ") end") i } 好像在一本Ruby的书中看到过,把第二行那个return关键字去掉就会打印并返回3了。 |
|
返回顶楼 | |
发表时间:2009-10-16
最后修改:2009-10-16
spider-dog 写道 def foo(i: Int): Int = { val bar = (j: Int) => { return j + 1 } bar(i) println("foo(" + i + ") end") i } 好像在一本Ruby的书中看到过,把第二行那个return关键字去掉就会打印并返回3了。 没错 fineqtbull 写道 @RednaxelaFx:你的代码很有趣,的确像你说的一样。为什么返回不是i的3呢,可否简单说明一下何为non-local return。
一般的函数调用-返回关系,应该在最后从被调用方返回到直接调用方,这就是一般的local return。 Non-local return则是跳过一层或多层的直接调用方,返回到更外层去。 上面的例子里,bar与一个匿名函数绑定。如果return实现的是local return语义,那么foo()中调用bar()后控制流仍然应该返回foo();但实际上Scala里的return有non-local return语义,无论嵌套在多深的匿名函数里,return都会把控制流返回到最靠近的具名函数的调用方。 def foo(i: Int): Int = { val bar = (j: Int) => { ((k: Int) => { return k + 1 })(j + 1) println("bar(" + j + ") end") j + 1 } bar(i) println("foo(" + i + ") end") i } 改成这样,return仍然是跳到foo的调用方去,而不是返回到bar()里。 所以在Scala(和Ruby)里,没事就别写return,特别是要小心匿名函数里写return。与其把return看成可选的,还不如抛弃命令式语言的“逐个命令执行”的思路,改用“面向表达式”的思路来看:一个表达式有值;一组表达式串在一起时取最后一个表达式的值作为整组的值。 |
|
返回顶楼 | |
发表时间:2009-10-16
这个算脚本语言吗?
|
|
返回顶楼 | |
发表时间:2009-10-16
@RednaxelaFX 谢谢说明,原来匿名和具名函数还有这样的差别呀,return也很强大,可以跨越多个方法调用。另外我知道有一个相似的return问题,用于try语句中,是不是和non-local return也有关系呀。
scala> def f(): Int = try { return 1 } finally { return 2 } f: ()Int scala> f() res18: Int = 2 上述代码较符合命令式编程的思路,最后的返回值是finally语句中的结果。 scala> def g(): Int = try { 1 } finally { 2 } g: ()Int scala> g() res19: Int = 1 而上述代码就比较“独特”了,与return语句不同,返回的是try中的1。 |
|
返回顶楼 | |
发表时间:2009-10-16
return的作用是强制改变控制流,但是finally块比它更霸道。try块后如果跟有finally块,则即便try块里有return,也必须在正常或非正常离开try后先进入finally块执行。此时如果finally块里有return,控制流就会被它跳回到caller。
用表达式观点看try...finally,整个表达式的值取决于try块里的最后一个表达式的值,除非有return。 |
|
返回顶楼 | |
发表时间:2009-10-16
fineqtbull 写道 scala> def g(): Int = try { 1 } finally { 2 } g: ()Int scala> g() res19: Int = 1 而上述代码就比较“独特”了,与return语句不同,返回的是try中的1。 这个谁能解释一下? 编译成Java代码会是什么样子? |
|
返回顶楼 | |