在從 C++ Template 到 Java Generic,一步一步來一文,我用 Java 的泛型語法改寫了一個 C++ 樣板類別。
我也用 PHP、JavaScript 和 Ruby 來做同樣的事,看看這些動態語言有沒有泛型處理能力。
我要用 Ruby 改寫的 C++ 樣板類別,其源碼同從 C++ Template 到 Java Generic,一步一步來。本文不再重複,直接說明 Ruby 的改寫過程。
Ruby 改寫過程
Ruby 語法與 C++ 語法的差異性較大。不細述改寫內容。
Ruby 中,變數名稱以 @ 開頭者,則為實體變數,且所有實體變數的存取屬性都是 private
。Ruby不允許 public
的資料成員,只能透過方法存取。
Cx 有兩個建構子,一個是無參數的預設建構子,另一個是一個參數的建構子。Ruby 可以用參數預設值的方式簡化建構子的改寫動作,寫成一個。
緊接著上面的內容,接著的要改寫 C++ 的 main()
。在 Ruby 中不需要指示程序進入點,直接寫即可。
在 C++ 中的樣板類別 Cx ,到了 Ruby 中之後,跟一般的類別沒兩樣。
因為動態語言的語義,基本上就是泛型的。
有些沒接觸過動態語言的人,對於泛型有一種奇怪的誤解,他們認為動態語言並沒有泛型語法,所以動態語言沒有泛型能力。我在C++和動態語言的泛型一文中曾經駁斥過這一論點。從語意看,動態語言其實就是泛型的。
移除 C++ 型別資訊,以 Ruby 語法改寫的 N, M, S 類別定義,也僅僅只剩兩行程式碼不同,這意味著我們可以進一步重構彙整。
前面提到在 Ruby 不允許 public 資料成員,所有資料成員都只能透過方法存取。而在本文的改寫過程中並沒有提到 Ruby 其實有簡便的屬性定義語法(Class Attribute Declarations)。如下列所示範。
C# 也有類似的語法,稱為自動實作屬性(Automatically implemented property),例如:
其實方法 attr_read, attr_accessor
都採用預設的方式存取資料成員。其預設方式如下:
方法 attr_read, attr_accessor
自動幫程序員完成取值與存值的程式碼。
相關文章
樂多舊網址: http://blog.roodo.com/rocksaying/archives/10934767.html