5 3 3 新增型別還是函式

2021-06-26 11:40:54 字數 1544 閱讀 4272

5.3.3 新增型別還是函式

正如我們早先提到過的,在 f# 和 c# 中,函式式資料型別 schedule 在乙個方向不可擴充套件:很難為事件新增新的型別。在 f# 中,困難的原因在於需要修改型別宣告,如果型別在共享庫中,必須重新編譯這個共享庫;同樣,在 c# 版本中,tag 屬性使得新增新型別更困難。另一方面,這種設計也有好處,能夠很容易地新增新的功能處理計畫。

我們來看一下函式式和物件導向方法之間的差異,圖 5.2 中的兩個類層次結構表示兩種可能的方法。在物件導向的版本中,所有的功能都封在虛擬方法中;函式式版本公開 tag 屬性,可用於標識表示哪乙個選項值。

圖 5.2 表示計畫,使用通常的物件導向設計(左圖),和帶 tag 屬性的函式式方法(右圖)

下面列出了我們在**示例中所看到的函式式程式設計風格(fp)與通常的物件導向風格的之間的主要區別:

■函式式程式設計風格版本能夠很容易為處理資料型別新增的新功能,只要寫乙個使用模式匹配的函式就能實現;但是,為型別新增新的表達很難。

■物件導向的版本新增新的型別表達很容易,只要寫乙個新的派生類並實現虛方法就能實現;但是,新增新的虛擬方法很難。

■在函式式程式設計風格版本中,乙個功能的**都在乙個地方,因此,與一類計算相關的所有**都在乙個函式中。

■在物件導向版本中,乙個型別的**都在乙個地方,因此,處理特定表達的所有**都在乙個類宣告中。

可以發現,關鍵問題是我們想讓新增新型別更容易,還是讓新增新函式更容易。經驗表明,在函式程式設計中,向現有型別中新增新的功能更常見。

如果你熟悉通常的設計模式,可能知道訪問者模式(visitor pattern),這是處理類似差別聯合一類資料結構的物件導向方法,我們在第七章討論遞迴差別聯合時還會談到,因為,它通常用於處理複雜的程式資料,而不是簡單的值;而是否選擇差別聯合,也要等到第七章才會討論到,因為這個問題更多地與程式資料有關,但是,可以先看看補充材料「在現實世界中的差別聯合」,有幾個使用差別聯合的例子。

在現實世界中的差別聯合

使用差別聯合實現類層次結構,有乙個很優雅的例子,即,.net 3.5 的 linq 專案引入的表示式(expression)型別,它是用來儲存表示式樹,表示解析後表示式源**的資料結構,(例如,1 + x)。對於表示式的每種型別,型別都有乙個派生類,如 binaryexpression 可以表示加法,和其他二元運算,constantexpression用於儲存文字。型別還有乙個屬性類似於 tag 屬性,但它的名字是 nodetype。一般而言,每當處理某種形式的源**,或由使用者輸入的簡單表示式,差別聯合可能是正確的選擇。

使用差別聯合的另乙個示例,是表示資料結構,如二叉樹。樹既可以是帶有一些值的葉子,也可能是內部節點,由兩個二叉樹組成的樹。在函式程式設計中,樹是經常使用的資料結構,因此,在第

八、第十和第十五章中都會看到。

在本章,我們討論了簡單值:任何簡單的表示為有限集合的可選值,應該始終選擇差別聯合。這是因為,對於這種值,幾乎可以肯定的是想要新增新的功能,而不是新增新的型別。在函式程式設計中,有一種差別聯合非常有用,所有的函式式語言中都有:在f# 中,稱為選項(option)型別。

5 3 3新增型別還是函式

5.3.3 新增型別還是函式 正如我們早先提到過的,在 f 和 c 中,函式 schedule 資料型別在乙個方向不可擴充套件 很難新增乙個新的事件的型別。在 f 中,出現困難的原因是,需要修改型別宣告 如果它在乙個共享庫中,必須重新編譯這個共享庫。同樣,在 c 版本中,我們有乙個 tag 屬性,這...

string 值型別還是引用型別

大家先來看一下下面的 吧!1using system 2using system.collections.generic 34 public class myclass5,a,s 12 1314 輸出的是abc,def 我們都知道陣列是引用型別的,請看一下段 1using system 2class...

關於string是值型別還是引用型別

當然了,string本質上肯定是引用型別,但是這個特殊的類卻表現出值型別的特點 判斷相等性時,是按照內容來判斷的,而不是位址 它肯定是乙個引用型別沒錯,兩個方面來看 1.class string繼承自object,而不是system.valuetype int32這樣的則是繼承於system.val...