ICE的slice定義注意事項

一、源文件規則

1、文件擴展名必須爲.ice

2、在使用#include來包含其他的ice定義文件時,只能使用<>,不能使用""。在使用路徑包含時,使用linux風格的斜線,不能使用windows風格的反斜線

3、每個slice定義文件中最好加上#ifndef的宏定義,防止文件的雙重包含

4、文件必須是utf-8編碼的


二、詞法規則

1、slice文件支持c++的單行和多行註釋

2、slice定義中的關鍵字均爲小寫

3、slice文件中關鍵字不能以下劃線開始和結尾,當然這一規則也是可以打破的,在編譯slice文件的時候使用“--underscore”的編譯選項

4、slice的關鍵字雖然是大小寫敏感的,但是爲了保證ice能夠映射到非大小寫敏感的系統,因此最好不要採用不同的大小寫拼寫規則來區分兩個關鍵字,即你可以認爲是非大小寫敏感的。

5、雖然說部分語言關鍵字不是slice的關鍵字,但是最好不要使用,因爲slice的編譯器會對這些語言相關的關鍵字進行特殊處理,從而帶來代碼可讀性的降低

6、如果以前定義的slice文件中標示符與新的ice版本規則衝突,可以使用反斜線"\"來表示關鍵字爲一個普通的標示符

7、slice定義文件中禁止標示符以“ice”開頭。當然這一規則也是可以打破的,在編譯slice文件的時候使用“--ice”的編譯選項

8、slice定義文件中禁止標示符以"Helper"、“Holder”、“Prx”、“Ptr”結尾。


三、名字空間

1、在全局的名字空間中只允許出現名字空間的定義,即slice文件定義的最頂層必須是名字空間定義Moudle XXX

2、可以再不同的文件中使用相同的名字空間,就像多個c++文件中定義名字空間的不同類型一樣


四、數據類型

1、slice提供的基本數據類型包括:bool、byte、short、int、long、float、double、string。擴展數據類型包括:enum、struct、sequence、dictionary。

2、特別注意slice不提供所謂的無符號類型,因爲在某些程序設計語言中,就不提供native的unsigned類型,因此slice無法做無符號類型的語言映射

3、slice的string字符串必須使用unicode字符集,同時不能包含0的。如果需要使用包含其他字符集或者0的串,可以考慮使用byte結構來存儲

4、布爾值bool的取值只能是flase或者true

5、byte類型在slice的語言映射中會始終保證是8字節的,同時在網絡傳輸過程中也不會受網絡和本地字節序的影響

6、slice的enum類型是不允許用戶來制定枚舉成員的取值的,但是slice能夠確保枚舉類型中後面的成員取值大於前面的成員取值,因此枚舉成員是可以做大小比較的。slice不允許定義空的枚舉類型,即枚舉類型中必須有成員定義

7、slice中struct不支持類型的嵌套定義,即不允許在一個struct數據類型中再次定義一個struct的數據類型

8、結構中的基本數據類型和枚舉類型支持在定義的時候指定默認值

9、需要使用變長的數據集合時,可以使用sequence來定義。sequence的一種特殊用法是用來標示可選值,因爲sequence數據成員可以是空的數據集合。爲了表示一個空的數據集合,我們一般這樣來定義:sequence<XXX> TypeOpt; TypeOpt Parameter; Opt的後綴一般迎來標示該序列集合是允許爲空的可選集合或者參數

10、需要使用類似map的類型映射結構時,可以使用dictionary來定義。但是dictionary的key字段是有約束的,只能是如下類型:byte、short、int、long、bool、string、enum、數據成員爲整形或者字符串的結構。

11、slice常量定義允許的類型:整形、浮點、字符串、枚舉。注意整型常量的取值不能帶長度標示(l、L、u、U);浮點和字符串常量的語法定義基本同c++;常量取值時需要設置允許範圍內的值,否則slice編譯時會提示錯誤;常量定義取值時是可以引用其他常量的,只要確保其取值範圍是合法的。


五、接口定義

1、接口操作必須包含如下信息:返回值、接口名稱、輸入參數類型和名稱(如果存在)、輸出參數類型和名稱(如果存在)。

2、接口操作在參數排版上要求輸出參數必須在輸入參數的後面,並且不支持輸入輸出參數,即參數的數據傳遞方向是單一的。不支持默認值參數

3、同一個接口內部不允許操作重名的。即不支持接口操作的重載

4、如果某一個操作不會改變其接口對象的狀態,請將其表示爲nonmutating。即類似c++的常量函數(函數名後加const)。這樣標示的好處是ice的運行環境能夠在函數調用過程發生底層的一些錯誤情況下更積極的重新嘗試,保證系統有更好的容錯性能。

5、如果一個操作在一個接口對象上連續執行兩次與一次的效果是一樣的,那麼爲了能夠讓系統有更好的容錯性能,請將接口表示爲idempotent。從這個角度去理解,那麼nonmutating操作也是idempotent的。

6、接口可以傳遞代理類型,即類似如c++的指針類型。這樣做的一個好處是客戶端能夠傳遞一個帶操作的數據結構給服務器端,這樣客戶端和服務器端能夠傳遞除了數據之外的操作實現。需要做的事情僅僅是在slice中定義一個接口的指針,注意是“接口”。

7、接口是可以繼承的,當然包含多重繼承。但是需要注意的一點是,多重繼承的多個基類中不能包含相同名稱的操作。

8、始終的有一個觀念就是,所有接口都共有同一個基類Object,但是你不能顯示的從Object繼承,這是slice隱私爲大家實現的。注意Object的O大寫了。這是關鍵字中的一個特例


六、異常處理

1、異常的定義有點類似結構,可以在其定義任何數據類型。但是和結構不同的是異常可以不包含任何數據成員

2、異常定義時也支持和常量一樣的默認值定義語法規則。即基本數據類型支持在定義的時候制定默認值

3、可以設置某一個接口操作會拋出特定類型的異常,當然在該接口操作實現過程中也只能拋出申明的異常,否則ice的會報運行時錯誤

4、爲了能夠更好的保證系統的向下兼容性,最好在系統初始定義時就設置好操作的異常(即使初始實現時是沒有異常拋出的)。

5、異常是支持繼承的。即可以向下擴展異常的信息。但是不支持多重繼承。可以再申明拋出基類異常的操作中拋出子類異常

6、服務器拋送給客戶端的異常有如下幾種情況:用戶異常、ObjectNotExistException、FacetNotExistException、OperationNotExistException、UnknownUserException(操作的實現拋出了一個未聲明的異常)、UnknownLocalException(系統未捕獲操作申明的異常)、UnknownException(語言系統的異常)


七、類

1、類在數據成員定義上與結構相同、在操作定義上與接口類似。他是一個兩中類型的混合物。類相比結構支持繼承擴展、支持多態、支持自引用,相比接口有具備數據屬性

2、爲了能夠具備更好的性能,如果struct就能夠完成的事情,不要大費周章的來弄個class來搞

3、一定要區分類的自引用和接口的自引用的差異化。類的自引用時確實的值存在,但是接口的自引用時指針存在,即不是值域空間。因此在一些操作中,需要從時間和空間的角度來考慮是採用值引用還是指針引用。

4、在接口或者類的操作中如果參數是一個類,那麼一定要注意,在客戶端和服務器端的交互中僅僅傳遞了發送方的類成員,其操作的行爲並沒有進行傳遞,因此不能確保其操作的行爲在客戶端和服務器端的解釋是一樣的。爲了能夠在客戶端和服務器端傳遞操作,最保險的做法是使用接口來代替類進行操作傳遞。當然如果你能保證客戶端和服務器端的操作行爲完全一致,用類來做不失爲一種好的做法,因爲在操作的執行上由於是在本地地址空間,而不會產生類似接口代理的RPC調用產生更重的調用開銷。

5、類可是實現一個或多個接口,在這種場景下,一個類實例的接口調用,一定要區分該操作時從接口繼承下來的,還是類擴展的。這樣才知道其調用實現時遠程的還是本地的。

6、類和接口一樣,不能重載操作。在繼承基類或者實現接口時,不能擴展和基類、實現接口相同的成員變量或者操作名稱

7、一定要注意,如果使用類來代替接口傳遞代理(即指針)給接收方,那麼僅僅是傳遞了一個代理,你只能理解是一個接口,而無法通過代理訪問類的數據成員。

8、在相互引用的類和接口定義中,前置聲明就成爲了一種不得不用的手段。


八、其他

1、每個擴展的類和接口都有一個類型ID,一般而言,類型ID 起頭是全局作用域(::),然後在後面附加包含該類型的各嵌套模塊的名字,最後再以該類型自身的名字結束

2、Object類提供了一些一些基本的操作:ice_ping、ice_isA、ice_id、ice_ids


九、編譯

1、slice2cpp [-h] [-v] [-DName] [-DName=Value] [-UName] [-IDir] [-E] [--output-dir Dir] [-d] [--ice] [--underscore] file

2、slice2html 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章