[转帖]在.NET平台上使用Scala语言(下):分析_Android, Python及开发编程讨论区_Weblogic技术|Tuxedo技术|中间件技术|Oracle论坛|JAVA论坛|Linux/Unix技术|hadoop论坛_联动北方技术论坛  
网站首页 | 关于我们 | 服务中心 | 经验交流 | 公司荣誉 | 成功案例 | 合作伙伴 | 联系我们 |
联动北方-国内领先的云技术服务提供商
»  游客             当前位置:  论坛首页 »  自由讨论区 »  Android, Python及开发编程讨论区 »
总帖数
1
每页帖数
101/1页1
返回列表
0
发起投票  发起投票 发新帖子
查看: 3179 | 回复: 0   主题: [转帖]在.NET平台上使用Scala语言(下):分析        下一篇 
wei.wang
注册用户
等级:少校
经验:1001
发帖:87
精华:0
注册:2013-8-29
状态:离线
发送短消息息给wei.wang 加好友    发送短消息息给wei.wang 发消息
发表于: IP:您无权察看 2013-9-9 10:33:34 | [全部帖] [楼主帖] 楼主

在上一篇文章中, 我们简单尝试了在Scala里编写.NET应用程序。这个过程并不困难,因为似乎Scala官方已经对此已经有较好的支持了。我们要做的只是“获取工具”,“编译成IL”,最后再“生成程序集”即可。那么,这些工具究竟做了些什么,Scala究竟又是如何支持.NET平台的,它的可用性究竟如何,我们还需要进一步的分析及尝试。[p=25, null, left]现在看第一个问题。我们知道从Scala源代码生成IL文件的脚本是scalac-net.bat。如果需要了解它做的事情,最直接的方法莫过于查看其中的内容。如果要看明白它的代码,可能需要我们对cmd命令有些了解——不过我也只是略知一二罢了,如果您对其了解不多其实也没有太大关系。经过合理推测,我们知道scalac-net.bat本身不会有什么功能,它只是调用编译器而已。因此,这个脚本文件的职责,无非是收集参数并执行编译器。于是我们打开scalac-net.bat,在众多for/if之中可以发现它最��执行了这样一个命令:

  1. %_JAVACMD% -Xbootclasspath/a:"%_BOOT_CLASSPATH%" %_JAVA_OPTS% %_PROPS% -cp "%_EXTENSION_CLASSPATH%" scala.tools.nsc.Main -target:msil %_ARGS%

复制代码


那么我们再调用scalac-net.bat的时候这行命令究竟是什么呢?对于此类问题,我们可以再它前面加上ECHO命令,即:

[p=25, null, left]

  1. ECHO %_JAVACMD% -Xbootclasspath/a:"%_BOOT_CLASSPATH%" %_JAVA_OPTS% %_PROPS% -cp "%_EXTENSION_CLASSPATH%" scala.tools.nsc.Main -target:msil %_ARGS%

复制代码


ECHO可以视为cmd的print命令,我们可以用它来观察和学习脚本。再次运行,便可以看到编译器的调用方式了:

  1. D:\scala-2.7.7.final\code> ..\bin\scalac-net.bat test.scala
  2. java -Xbootclasspath/a:"D:\SCALA-~1.FIN\bin\..\lib\scala-library.jar" -Xmx256M -Xms16M -Dscala.home="D:\SCALA-~1.FIN\bin\.." -Denv.classpath="" -Dmsil.libpath="D:\SCALA-~1.FIN\bin\..\lib\predef.dll;D:\SCALA-~1.FIN\bin\..\lib\scalaruntime.dll;D:\SCALA-~1.FIN\bin\..\lib\mscorlib.dll" -Dmsil.ilasm="c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe"  -cp "D:\SCALA-~1.FIN\bin\..\lib\mscorlib.dll;D:\SCALA-~1.FIN\bin\..\lib\predef.dll;D:\SCALA-~1.FIN\bin\..\lib\sbaz-tests.jar;D:\SCALA-~1.FIN\bin\..\lib\sbaz.jar;D:\SCALA-~1.FIN\bin\..\lib\scala-compiler.jar;D:\SCALA-~1.FIN\bin\..\lib\scala-dbc.jar;D:\SCALA-~1.FIN\bin\..\lib\scala-library.jar;D:\SCALA-~1.FIN\bin\..\lib\scala-swing.jar;D:\SCALA-~1.FIN\bin\..\lib\scalaruntime.dll" scala.tools.nsc.Main -target:msil test.scala

复制代码


可以看出,这是在运行一个java程序,并且提供了很多参数。不过参数很多,内容也很乱。不过乱的原因在于其中对于各式命令或者库文件的引用都使用的完整路径。经过换行,相对路径调整,并去除一些明显无用的参数内容(如-cp,即classpath里的dll文件),我们发现其实大约这样的:

  1. D:\scala-2.7.7.final\code> ..\bin\scalac-net.bat test.scala
  2. java
  3.   -Xbootclasspath/a:"..\lib\scala-library.jar"
  4.   -Xmx256M
  5.   -Xms16M
  6.   -Dscala.home=".."
  7.   -Denv.classpath=""
  8.   -Dmsil.libpath="..\lib\predef.dll;..\lib\scalaruntime.dll;..\lib\mscorlib.dll"
  9.   -Dmsil.ilasm="c:\Windows\Microsoft.NET\Framework\v2.0.50727\ilasm.exe"
  10.   -cp "..\lib\sbaz-tests.jar;..\lib\sbaz.jar;..\lib\scala-compiler.jar;..\lib\scala-dbc.jar;..\lib\scala-library.jar;..\lib\scala-swing.jar;"
  11.   scala.tools.nsc.Main
  12.   -target:msil
  13.   test.scala

复制代码
您可以执行整理后的命令,效果一致。经过一番摸索,再配合scalac.bat -help的输出,我们可以观察出命令的具体意义,例如:

  • Scala编译器其实是一个Java程序,入口是scala.tools.nsc.Main
  • -Dmsil.libpath表明编译时所引用的.NET程序集。
  • -Dmsil.ilasm表明ilasm.exe文件的路径,如果需要直接生成程序集则需要进行指定。
那么假设我们已经编译生成了一个test.exe文件,现在使用.NET Reflector来观察它的信息: 北京联动北方科技有限公司
可见test.exe依赖另外三个程序集,它们按照依赖关系分别是:
    mscorlib.dll:定义了一个程序的基础需求。
    scalaruntime.dll:依赖mscorlib.dll,定义了Scala语言中的各种基础类型。
    predef.dll:依赖mscorlib.dll及scalaruntime.dll,定义了scala的基础类库。

看上去并没有什么问题,不是吗?但是,经过简单的思考,似乎又不是那么一回事情。好比,您是否觉得一个Scala程序的依赖实在少了一些?例如您平时写程序时能否仅仅依赖mscorlib.dll,而不使用System.dll或System.Core.dll等其他程序集?那么,为什么Scala便可以仅仅基于mscorlib.dll而构建predef.dll呢?为此,我们简单比较一下predef.dll与Java平台上Scala的标准库——scala-library.jar。首先是predef.dll: 北京联动北方科技有限公司
其次是scala-library.jar中的定义:
北京联动北方科技有限公司
可以看出,Scala标准库中定义了比predef.dll中更多的类库。例如Scala一直引以为傲的Actor类库,即scala.actors命名空间。换句话说,.NET平台上的Scala并不支持Java平台上的许多高级功能——这样似乎可以理解为什么它只需依赖mscorlib.dll就足够了。不过“标准类库少”是坏事还是好事倒也不能轻易下结论。如果说这是坏事——类库少自然是坏事。那么“好事”又从何谈起呢?我的理解是:Scala��竟是为Java平台设计的语言,它本可不必对.NET提供支持。也就是说,.NET平台只是Scala的“副业”。如果说,因为IL和Java Code相近(或者说有很大程度的“包含”关系),那么编译器在写起来相对问题不大,但“类库”就无法讨巧了。如果.NET类库跟得太紧,那么我反而要怀疑它的质量是否成熟。在使用Scala时,我主要关注的其实是“编译器”及最终生成的IL,我并没有期望能够使用Scala在.NET平台上编写程序。对此,编译器是否成熟对我们来说可能更加重要。因此,.NET类库少也并不是坏事——毕竟.NET Framework已经提供了足够的功能,不是吗?是吗?如果您比较心细,您应该已经从第一幅图中看出问题来了。我特意将焦点放在mscorlib.dll上,目的便是展示它的版本信息,即:

  1. mscorlib, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=b77a5c561934e089

复制代码


如果您关注一下平时写程序时所使用的mscorlib.dll,会发现它是这样的:

  1. mscorlib, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e




赞(0)    操作        顶端 
总帖数
1
每页帖数
101/1页1
返回列表
发新帖子
请输入验证码: 点击刷新验证码
您需要登录后才可以回帖 登录 | 注册
技术讨论