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

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

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

          關于Ceylon

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

          編寫一個簡單的程序

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

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

          Ceylon沒有Java風格的靜態方法,但是你可以使用頂層方法來充當同樣的角色。靜態方法存在的問題是它打亂了程序的塊結構。Ceylon擁有嚴格的塊結構--一個內嵌的塊總是可以在所有包含它的塊中被訪問。這與Java的靜態方法不同。
          這個方法使用了void關鍵字,這表示方法沒有返回值。當方法被執行時,它調用另一個頂層方法writeLine(),這個方法在控制臺中顯示它的參數。

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

          可能對void方法有一個返回類型很不解。對此的解釋就是Ceylon內所有的方法都是函數。(但未必都是函數--比如hello(),一個Ceylon函數能夠有邊緣效應。)

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

          添加內嵌的文檔

          通常給像hello()這樣重要的方法上添加注釋文檔是一個好習慣。一個方式就是使用C語言風格的注釋,就像下面這樣:
          /* 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文檔編譯器輸出中。文檔編譯器還將支持其它幾個注解,包括by,用來指定程序作者;see,用來關聯其它代碼元素;以及throws,報告用戶程序執行拋出的異常類型。
          doc "The classic Hello World program" 
          by 
          "Gavin" 
          see (goodbye) 
          throws (IOException)
          void hello() { 
              writeLine(
          "Hello, World!");
          }

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

          字符串和字符串內插

          Hello World程序--現在廣泛流行--提供非常有限的用戶體驗。一個更典型的例子在不同的運行時產生不同的輸出。

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

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

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

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

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

          處理沒找到的對象

          大多數程序都要求接收輸入并產生輸出,并且程序依賴于接收的輸入。當然,這么做對用戶來說有點苛刻,但是,一些額外的工作必須做!

          對此,提供一個改良版本的Hello World程序,其從命令行接收一個名字作為輸入。我們必須考慮在命令行什么都沒輸入的情況,這樣就能給我們一個機會去體驗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對象有一個arguments屬性,它持有命令行參數的Sequence(順序)。本地變量name被這些參數初始化,參數如果存在的話,本地變量被聲明為String類型,否則他可能包含一個null值。if(exists...)控制結構用來初始化本地非空變量greeting,如果name不是null的話就內插到消息字符串中。最終,消息被輸出到控制臺。
          這與Java不一樣,本地變量,參數和屬性都可以包含null值,但必須明確聲明其類型。這與其它語言持有類型安全的null值不同,在Ceylon中可選的類型不是一個封裝定值的algebraic數據類型,而是一個ad-hoc union type(聯合類型)。語法T|S表示聯合T和S。一個可選的類型Noting|X代表任何類型,X是一個定值類型。Ceylon允許我們使用縮寫X?代表Noting|X。
          doc "The type of null."
          shared 
          abstract class Nothing() 
                  of nothing
                  
          extends Void() {}

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

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

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

          事實上,沒有可能在一個可選類型的表達式里使用==操作符,你不能像在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...)結構外部使用變量name,這個語法在很多時候被首選使用。

          默認參數

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

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

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

          還有更多。。。

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

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

          評論

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

          游戲支付平臺www.hwd518.com  回復  更多評論   

          導航

          <2011年5月>
          24252627282930
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          統計

          隨筆分類(139)

          Linux內核

          搜索

          •  

          積分與排名

          • 積分 - 319919
          • 排名 - 178

          最新評論

          閱讀排行榜

          主站蜘蛛池模板: 清丰县| 尤溪县| 永吉县| 庄浪县| 龙里县| 义马市| 云南省| 溆浦县| 波密县| 溧水县| 连平县| 静宁县| 磐安县| 诸城市| 滨州市| 武宁县| 梁山县| 日照市| 五河县| 乌拉特中旗| 陵川县| 耿马| 丁青县| 潢川县| 来安县| 邢台县| 疏附县| 佛山市| 南京市| 江达县| 太康县| 韩城市| 长白| 彭州市| 虎林市| 赤壁市| 武定县| 喀喇沁旗| 南平市| 江孜县| 紫阳县|