Ceylon語言介紹第一部分(翻譯)——Hibernate之父的又一力作

          原文:http://in.relation.to/Bloggers/IntroductionToCeylonPart1

          這是Ceylon語言系列文章的第一部分。要注意的是語言的特性可能在最終版發(fā)布之前發(fā)生改變。

          關(guān)于Ceylon

          Ceylon是一門新的語言,它運(yùn)行在Java虛擬機(jī)上,目前正有我所在的小組開發(fā),它隸屬于RedHat。我們都是Java和Java生態(tài)系統(tǒng)的粉絲,因?yàn)樗膶?shí)用性、廣闊的文化氛圍和開發(fā)社區(qū)、天生適用于商業(yè)應(yīng)用以及可移植性。然而我們必須承認(rèn)這門語言和其現(xiàn)有的類庫,已經(jīng)過了15年的發(fā)展,它不能再提供更好的功能來解決現(xiàn)在的商業(yè)問題。
          • Ceylon的設(shè)計(jì)目標(biāo)包括:
          • Java和C#開發(fā)者可以很容易的學(xué)習(xí)和掌握。
          • 消除了一下Java的啰嗦語法,使其容易閱讀。
          • 更加類型安全。
          • 提供一個(gè)聲明式的語法來表達(dá)層級(jí)信息,比如定義用戶接口、結(jié)構(gòu)化數(shù)據(jù)以及系統(tǒng)配置,這導(dǎo)致了Java平臺(tái)過度的依賴于XML。
          • 支持不變對(duì)象和高級(jí)函數(shù)(功能)
          • 極好的元數(shù)據(jù)編程支持,這使得編寫框架變得非常容易
          • 提供內(nèi)置模塊解決方案
          最重要的是,Ceylon的設(shè)計(jì)目的是讓大型團(tuán)隊(duì)更好的協(xié)作
          Ceylon編譯器還沒有完成,所以你還不能使用Ceylon編寫代碼。不管怎樣,我愿意讓社區(qū)參與語言和SDK的開發(fā),所以這個(gè)系列文章是給對(duì)Ceylon感興趣的人一個(gè)提前預(yù)覽。
          讓我們從頭開始吧。

          編寫一個(gè)簡(jiǎn)單的程序

          這是一個(gè)經(jīng)典的例子程序。
          void hello() { 
              writeLine(
          "Hello, World!");
          }

          這個(gè)方法在控制臺(tái)打印出“Hello, World!”。這是一個(gè)頂層方法就像C語言函數(shù)--它直屬于包含它的包中,它不是一個(gè)任何類型的成員。你不需要接收一個(gè)對(duì)象來調(diào)用頂層方法,你只要像下面這樣就可以調(diào)用它:
          hello();

          Ceylon沒有Java風(fēng)格的靜態(tài)方法,但是你可以使用頂層方法來充當(dāng)同樣的角色。靜態(tài)方法存在的問題是它打亂了程序的塊結(jié)構(gòu)。Ceylon擁有嚴(yán)格的塊結(jié)構(gòu)--一個(gè)內(nèi)嵌的塊總是可以在所有包含它的塊中被訪問。這與Java的靜態(tài)方法不同。
          這個(gè)方法使用了void關(guān)鍵字,這表示方法沒有返回值。當(dāng)方法被執(zhí)行時(shí),它調(diào)用另一個(gè)頂層方法writeLine(),這個(gè)方法在控制臺(tái)中顯示它的參數(shù)。

          連同void關(guān)鍵字,還有一個(gè)命名為Void的類型,其再任何void方法中被返回,這也是Ceylon類型系統(tǒng)的根類型。
          doc "The root type, supertype of
                both Object (definite values) 
                and Nothing (the 
          null value)."
          see (Nothing, Object)
          shared 
          abstract class Void() {}

          可能對(duì)void方法有一個(gè)返回類型很不解。對(duì)此的解釋就是Ceylon內(nèi)所有的方法都是函數(shù)。(但未必都是函數(shù)--比如hello(),一個(gè)Ceylon函數(shù)能夠有邊緣效應(yīng)。)

          在一個(gè)非常抽象層里,每個(gè)方法都接受參數(shù)并有返回結(jié)果。對(duì)于Void類型,簡(jiǎn)單來說就是提供表示未知值和未知類型的一種途徑。你可以給Void分配任何值,包括null,但是它無法被再次回收,即使知道它的類型值是什么。因此理論上void方法有返回值,只是我們無法知道關(guān)于它值的任何信息。現(xiàn)在這聽起來可能沒什么用處,但是當(dāng)我們討論first-class函數(shù)和Ceylon類型安全的元數(shù)據(jù)模型時(shí)將證明其非常有用。

          添加內(nèi)嵌的文檔

          通常給像hello()這樣重要的方法上添加注釋文檔是一個(gè)好習(xí)慣。一個(gè)方式就是使用C語言風(fēng)格的注釋,就像下面這樣:
          /* The classic Hello World program */ 
          void hello() {
              writeLine(
          "Hello, World!");
          }

          或者像這樣:
          //The classic Hello World program 
          void hello() {
              writeLine(
          "Hello, World!");
          }

          但是更好的方式是使用doc注解來寫注釋。
          doc "The classic Hello World program" 
          void hello() {
              writeLine(
          "Hello, World!");
          }

          doc注解包含的文檔被包含在Ceylon文檔編譯器輸出中。文檔編譯器還將支持其它幾個(gè)注解,包括by,用來指定程序作者;see,用來關(guān)聯(lián)其它代碼元素;以及throws,報(bào)告用戶程序執(zhí)行拋出的異常類型。
          doc "The classic Hello World program" 
          by 
          "Gavin" 
          see (goodbye) 
          throws (IOException)
          void hello() { 
              writeLine(
          "Hello, World!");
          }

          同樣還有一個(gè)deprecated注解,用來說明程序元素在將來的版本中會(huì)被移除。
          注意,當(dāng)一個(gè)注解的參數(shù)是字面原文形式,那么久不需要有關(guān)閉括號(hào)。
          像doc,by,see和deprecated這類的注解不是一個(gè)關(guān)鍵字。它們只是普通的標(biāo)識(shí)符。同樣的對(duì)于語言中定義的注解:abstract,variable,shared,formal,actual和friends也都不是關(guān)鍵字。但void是關(guān)鍵字。

          字符串和字符串內(nèi)插

          Hello World程序--現(xiàn)在廣泛流行--提供非常有限的用戶體驗(yàn)。一個(gè)更典型的例子在不同的運(yùn)行時(shí)產(chǎn)生不同的輸出。

          讓我們來詢問我們的程序,以便它告訴我們更多關(guān)于它自己的信息。
          doc "The Hello World program 
                version 1.1!"
          void hello() { 
              writeLine(
          "Hello, this is Ceylon " process.languageVersion
                        
          " running on Java " process.javaVersion "!");
          }

          我們能看到Ceylon的字符串提供的兩個(gè)好處。第一就是可以分割字符串為多行,這對(duì)于在doc注解中寫文檔非常有幫助。第二個(gè)就是我們可以在字符串內(nèi)部插入表達(dá)式,從技術(shù)上來講,一個(gè)帶有表達(dá)式的字符串不在是一個(gè)真正的字符串了,而被看做一個(gè)字符串模板。
          一個(gè)字符串表達(dá)式必須開頭和結(jié)尾都必須是字符串,下面的語法是錯(cuò)誤的:
          writeLine("Hello, this is Ceylon " process.languageVersion); //compile error!

          在最后加上一個(gè)空的字符串就能修正上面例子的錯(cuò)誤。
          writeLine("Hello, this is Ceylon " process.languageVersion "");

          注意,在Ceylon中這不是唯一連接字符串的方法。其實(shí)這只是對(duì)于在不變的字符串中插入變量或表達(dá)式有用。+操作符可作為另外一種選擇,還有更多靈活的例子:
          writeLine("Hello, this is Ceylon " + process.languageVersion + 
                    
          " running on Java " + process.javaVersion + "!");

          但是不要看到這兩種方式的輸出是一樣的就認(rèn)為它們是等價(jià)的。+操作符僅僅是對(duì)表達(dá)式求值并產(chǎn)生一個(gè)不可變的String對(duì)象。而String模板是一個(gè)Gettable<String>的表達(dá)式,其不馬上對(duì)內(nèi)插表達(dá)式求值(有點(diǎn)像Hibernate里的懶加載)。如果你打印String模板對(duì)象兩次,你可能會(huì)看到兩個(gè)不同的輸出。其實(shí),String模板是一種closure(閉包)--一個(gè)重要的概念,我將在后面介紹。

          處理沒找到的對(duì)象

          大多數(shù)程序都要求接收輸入并產(chǎn)生輸出,并且程序依賴于接收的輸入。當(dāng)然,這么做對(duì)用戶來說有點(diǎn)苛刻,但是,一些額外的工作必須做!

          對(duì)此,提供一個(gè)改良版本的Hello World程序,其從命令行接收一個(gè)名字作為輸入。我們必須考慮在命令行什么都沒輸入的情況,這樣就能給我們一個(gè)機(jī)會(huì)去體驗(yàn)Ceylon如何處理Null值,這可與Java于C#的處理方式有著很大的不同。
          doc "Print a personalized greeting" 
          void hello() {
              String
          ? name = process.arguments.first; 
              String greeting; 
              
          if (exists name) {
                  greeting 
          = "Hello, " name "!";
              }
              
          else {
                  greeting 
          = "Hello, World!"
              }
              writeLine(greeting);
          }

          process對(duì)象有一個(gè)arguments屬性,它持有命令行參數(shù)的Sequence(順序)。本地變量name被這些參數(shù)初始化,參數(shù)如果存在的話,本地變量被聲明為String類型,否則他可能包含一個(gè)null值。if(exists...)控制結(jié)構(gòu)用來初始化本地非空變量greeting,如果name不是null的話就內(nèi)插到消息字符串中。最終,消息被輸出到控制臺(tái)。
          這與Java不一樣,本地變量,參數(shù)和屬性都可以包含null值,但必須明確聲明其類型。這與其它語言持有類型安全的null值不同,在Ceylon中可選的類型不是一個(gè)封裝定值的algebraic數(shù)據(jù)類型,而是一個(gè)ad-hoc union type(聯(lián)合類型)。語法T|S表示聯(lián)合T和S。一個(gè)可選的類型Noting|X代表任何類型,X是一個(gè)定值類型。Ceylon允許我們使用縮寫X?代表Noting|X。
          doc "The type of null."
          shared 
          abstract class Nothing() 
                  of nothing
                  
          extends Void() {}

          null值關(guān)聯(lián)一個(gè)Nothing類型的實(shí)例,但是它不是一個(gè)Object的實(shí)例。因此這是一種簡(jiǎn)單分配本地變量為Null(不是一個(gè)可選類型)的方式。
          doc "Represents a null reference."  
          object nothing 
          extends Nothing() {}

          doc 
          "Hides the concrete type of nothing."  
          shared Nothing 
          null = nothing;

          Ceylon編譯器也不允許你最T類型的值做任何“危險(xiǎn)”的事情,在Java里這樣會(huì)拋出NullPointerException。if(exists...)結(jié)構(gòu)讓我們從X?類型提取X類型的值,從而允許我們調(diào)用X值的方法。

          事實(shí)上,沒有可能在一個(gè)可選類型的表達(dá)式里使用==操作符,你不能像在Java中那樣使用if(x==null)。這有助于避免像Java中的不良操作==,x==y在Java中如果x和y都是null將返回true.

          在if(exists...)條件中可以聲明本地變量name:
          String greeting; 
          if (exists String name = process.arguments.first) {
              greeting 
          = "Hello, " name "!";

          else {
              greeting 
          = "Hello, World!"
          }
          writeLine(greeting);

          自從我們不能再if(exists...)結(jié)構(gòu)外部使用變量name,這個(gè)語法在很多時(shí)候被首選使用。

          默認(rèn)參數(shù)

          一個(gè)方法參數(shù)可以指定一個(gè)默認(rèn)值。
          void hello(String name="World") {
              writeLine(
          "Hello, " name "!");
          }

          這樣我們就不需要在調(diào)用方法時(shí)指定參數(shù)值。
          hello(); //Hello, World!
          hello("JBoss"); //Hello, JBoss!

          默認(rèn)參數(shù)必須在所有必須參數(shù)列表的最后面。
          Ceylon同樣支持參數(shù)序列,使用T...語法。我們將在for循環(huán)序列中講述。

          還有更多。。。

          在第二部分,我們將看到如何定義一個(gè)自身類型:classes,interfaces和objects.

          posted on 2011-05-24 07:25 kuuyee 閱讀(2893) 評(píng)論(1)  編輯  收藏 所屬分類: JEERuby/Python/Ceylon

          評(píng)論

          # re: Ceylon語言介紹第一部分(翻譯)——Hibernate之父的又一力作[未登錄] 2011-10-20 02:39 1

          游戲支付平臺(tái)www.hwd518.com  回復(fù)  更多評(píng)論   

          導(dǎo)航

          <2011年10月>
          2526272829301
          2345678
          9101112131415
          16171819202122
          23242526272829
          303112345

          統(tǒng)計(jì)

          隨筆分類(139)

          Linux內(nèi)核

          搜索

          •  

          積分與排名

          • 積分 - 320259
          • 排名 - 178

          最新評(píng)論

          閱讀排行榜

          主站蜘蛛池模板: 南投县| 宁夏| 辽宁省| 铁力市| 前郭尔| 合江县| 龙江县| 郧西县| 双峰县| 皮山县| 牙克石市| 肇州县| 灯塔市| 杨浦区| 藁城市| 江源县| 行唐县| 措勤县| 开封县| 宽甸| 尼玛县| 松溪县| 乌鲁木齐县| 临江市| 汉中市| 大新县| 台南市| 日照市| 毕节市| 柏乡县| 长汀县| 北流市| 临夏县| 宁安市| 太康县| 上栗县| 松江区| 葫芦岛市| 通山县| 桂林市| 江永县|