Scala登陸.NET平臺(tái)
原創(chuàng)【51CTO外電頭條】Miguel Garcia是瑞士洛桑理工大學(xué)的Scala語(yǔ)言開(kāi)發(fā)小組成員,多年來(lái)他一直在努力將Scala的生產(chǎn)力移植到.NET平臺(tái),為開(kāi)發(fā)者提供幫助。現(xiàn)在多年的工作已經(jīng)達(dá)到了一個(gè)重要的里程碑。在Miguel的訪談中,他稱已經(jīng)可以在.NET上使用Scala,并預(yù)計(jì)這個(gè)微軟資助的重要項(xiàng)目將來(lái)會(huì)有更了不起的成就。
51CTO編輯推薦:Scala語(yǔ)言編程入門指南
為什么需要讓Scala在.NET上運(yùn)行?
Miguel:
總的來(lái)說(shuō)有很多原因,這對(duì)開(kāi)發(fā)者和企業(yè)兩方面都非常具有吸引力。Scala是一個(gè)精確的并且具有高度生產(chǎn)力的編程語(yǔ)言。在.NET上使用Scala,開(kāi)發(fā)者不僅能夠更快速的開(kāi)發(fā)出各種應(yīng)用,而且能夠在JVM和.NET這兩個(gè)主流行業(yè)平臺(tái)之間進(jìn)行跨平臺(tái)部署。
這對(duì)于開(kāi)發(fā)者來(lái)說(shuō)意味更多,因?yàn)橹恍枰獙W(xué)習(xí)一種語(yǔ)言就可以在兩種環(huán)境里創(chuàng)建應(yīng)用。從企業(yè)的觀點(diǎn)看,這也能夠更好的利用***資源,因?yàn)閮?yōu)秀的程序員可以輕松的跨越兩個(gè)平臺(tái),減少了培訓(xùn)成本,增加了靈活性,降低了風(fēng)險(xiǎn)。.NET平臺(tái)集成了多種語(yǔ)言,Scala的互操作性也很好,你可以使用現(xiàn)有的.NET庫(kù)或現(xiàn)有的應(yīng)用,不需要使用Scala重寫。最終的效果是原先只能分別在.NET和JVM環(huán)境中使用的工具和應(yīng)用都可以從一個(gè)環(huán)境移植到另一個(gè)環(huán)境,這是一個(gè)多贏的局面。從目前的情況看,Scala和.NET二者結(jié)合的非常好,對(duì)Scala開(kāi)發(fā)者來(lái)說(shuō)幾乎不會(huì)察覺(jué)到是在.NET上運(yùn)行。
現(xiàn)在就能在.NET上運(yùn)行Scala程序了嗎?
Miguel:答案很簡(jiǎn)單,是的,只是目前還有一點(diǎn)局限,但到今年秋天就會(huì)完全解決。
如果你想把正在JVM上運(yùn)行的Scala程序移植到.NET上,需要做的只是使用Scala.NET編譯器重新編譯一遍,就可以在.NET上運(yùn)行了。
現(xiàn)在碰到的主要局限就是Scala程序還不能使用.NET中那些用到CLR泛型的類庫(kù),比如.NET集合類。當(dāng)然這只是一個(gè)小限制了,其他的功能全部可用,而且到今年秋天.NET泛型也能全部支持。
怎樣在.NET上開(kāi)發(fā)Scala程序呢?
Miguel:你可以直接在MS Visual Studio里開(kāi)發(fā)。到今年秋天Visual Studio的Scala插件就能支持人們期望的各種基本功能了,具體地說(shuō),IDE、代碼自動(dòng)完成、代碼瀏覽、斷行、表達(dá)式和異常報(bào)告等等這些。
目前的Scala.NET編譯器也已經(jīng)非常強(qiáng)大了,它能夠?qū)ψ约哼M(jìn)行編譯,大概由十萬(wàn)行Scala代碼組成?,F(xiàn)在的插件還不支持代碼自動(dòng)完成和代碼瀏覽,所以我有時(shí)還是會(huì)選擇使用Eclipse或是Intellij在JVM上編寫代碼,然后在Visual Studio中做最終的調(diào)試。
你們是怎樣做到的?
Miguel:主要需要克服的困難是Scala程序大量使用了Java JDK,而Java JDK在.NET環(huán)境中是不被支持的,所以Scala編譯器必須要針對(duì).NET而重新生成代碼。
Java社區(qū)早已經(jīng)開(kāi)發(fā)出IKVM虛擬機(jī),可以把Java程序轉(zhuǎn)換成MSIL(Microsoft Intermediate Language,微軟中間語(yǔ)言),此外還有一個(gè).NET類庫(kù)用來(lái)提供基本的JDK支持。IKVM是Jeroen Frijters很早以前就一直倡導(dǎo)的一個(gè)開(kāi)源項(xiàng)目,也是為了遵循Java“一次編寫,到處運(yùn)行”的原則,IKVM存在很長(zhǎng)時(shí)間了,作為開(kāi)源項(xiàng)目非常成功,也有可靠的商業(yè)支持。IKVM類庫(kù)是我們用來(lái)初始Scala.NET編譯器的關(guān)鍵內(nèi)容,而且給我們提供了將Scala類庫(kù)搬上.NET的優(yōu)良基礎(chǔ)。
說(shuō)來(lái)Scala.NET編譯器的歷史也很長(zhǎng)了,但剛開(kāi)始主要是集中在編譯器的愛(ài)好者和黑客群體里,當(dāng)時(shí)他們中有些人開(kāi)發(fā)出了跨平臺(tái)的編譯器。在我進(jìn)入的時(shí)候,跨平臺(tái)編譯器已經(jīng)成型,但它還不能在.NET環(huán)境中啟動(dòng)自己。這意味著必須有一個(gè)能夠自己編譯自己的Scala.NET編譯器,實(shí)際上這是一個(gè)先有雞還是先有蛋的經(jīng)典問(wèn)題。
當(dāng)時(shí)的跨平臺(tái)編譯器運(yùn)行良好,但只能在JDK上運(yùn)行。依靠大量的JDK API,這和目前的Scala應(yīng)用一樣。現(xiàn)在很多Scala開(kāi)發(fā)者還是習(xí)慣使用JDK中的功能,即使這些功能在Scala SDK上也已經(jīng)提供了。所以說(shuō)我們雖然有了跨平臺(tái)編譯器,但缺乏方法,能夠用.NET類庫(kù)的功能自動(dòng)替換那些JDK的功能。
IKVM編譯器能夠提取JVM字節(jié)碼轉(zhuǎn)換為.NET的Assembly類庫(kù)。推進(jìn)到字節(jié)碼級(jí)別雖然是前進(jìn)了一大步,但并沒(méi)有給我們帶來(lái)真正的開(kāi)端,因?yàn)槲覀円琅f沒(méi)有擺脫對(duì)JDK的依靠。所以我們的任務(wù)就變成了創(chuàng)建一個(gè)前端處理器,能夠修改Scala的源代碼,將JDK直接替換為IKVM類庫(kù)中的.NET相同功能,一種映射機(jī)制。
具體是怎樣映射的呢?
Miguel:***步是創(chuàng)建源代碼級(jí)所需要的初始化轉(zhuǎn)換。下一階段是擴(kuò)展Scala編譯器來(lái)應(yīng)用這些轉(zhuǎn)換。Scala編譯器是模塊化的,支持各種插件,因此應(yīng)用起來(lái)很方便,但并不是所有的編譯器都能夠那么靈活的做到。我們創(chuàng)建了一個(gè)新的Scala插件JDK2IKVM用來(lái)在批模式下完成源代碼轉(zhuǎn)換。得到的源代碼引用IKVM類庫(kù),經(jīng)過(guò)標(biāo)準(zhǔn)的編譯器流程生成MSIL字節(jié)碼。這就是我們現(xiàn)在的Scala.NET,能夠自己編譯自己的Scala編譯器。實(shí)際操作中我們會(huì)反復(fù)進(jìn)行多次編譯/轉(zhuǎn)換環(huán)節(jié)來(lái)完成全部的功能轉(zhuǎn)換。
在后臺(tái)我們使用了重構(gòu)技術(shù),這種技術(shù)也可以用于其它的平臺(tái)移植,例如將Java.IO自動(dòng)轉(zhuǎn)換為Scala.IO。當(dāng)然Scala.NET編譯器本身也就是一個(gè)Scala應(yīng)用,因此對(duì)于任何JVM上的Scala應(yīng)用都會(huì)有效,這很好理解。
原始類型(Primitive Type)的兼容性怎樣?
Miguel:.NET的CLR提供的原始類型是JVM類型的超集,從編譯器的角度看來(lái)它們轉(zhuǎn)換起來(lái)很容易。字符串和數(shù)值等等都能夠完成轉(zhuǎn)換,從我們開(kāi)始測(cè)試起就沒(méi)有發(fā)現(xiàn)什么困難情況。IKVM在IKVM社區(qū)已經(jīng)使用了很多年了。
接下來(lái)準(zhǔn)備做什么?
Miguel:剛才提到了,接下來(lái)我們要擴(kuò)展Visual Studio插件,加入對(duì).NET泛型的支持,提供完整的IDE功能。此外SDK還有一些部分比如并行集合等需要針對(duì).NET環(huán)境進(jìn)行修改。轉(zhuǎn)型映射還會(huì)擴(kuò)展到支持一些開(kāi)發(fā)者常用的基本庫(kù)比如IO等等。
原文標(biāo)題:Scala comes to .NET
【編輯推薦】