- 最後登錄
- 2023-9-20
- 在線時間
- 0 小時
- 註冊時間
- 2011-11-27
- 閱讀權限
- 20
- 精華
- 0
- UID
- 10591431
- 帖子
- 37
- 積分
- 249 點
- 潛水值
- 6131 米
| 本帖最後由 thebestjavauser 於 2016-8-24 02:05 AM 編輯
因為 Java 的類型操作永遠在 value 和 type 層次啊(超可憐XD)
要是你用可以到達 kind 或更高層次的語言(例如 C++, Scala) 就沒有這些問題了
補個程式碼好了- /* bird 繼承所有傳入的 Bases */
- template <typename... Bases>
- class bird : public Bases...
- { ... };
- /* 做出一個 base class */
- struct flyable
- { virtual void fly () { ... } };
- /* 再一個 base class */
- struct speakable
- { virtual void speak () { ... } };
- /* 你高興有幾個 base class 就做幾個 */
- struct singable
- {
- /*
- * 每種鳥叫聲不同,可能也不只鳥會唱歌,或許有其他的物種也會繼承這個 base,因此
- * 不實作預設的 sing 函式,留給 derived classes 實做
- */
- virtual void sing () = 0;
- };
- /*
- * 鸚鵡會飛會說話,所以把 flyable, speakable 傳給 bird,這裡的 bird 會繼承 flyable
- * 和 speakable,parrot 再繼承繼承了這兩個 base 的 bird
- */
- class parrot : public bird<flyable, speakable>
- {
- public:
- void fly () override { ... } // 如果有需要,你可以在此 override base 的函式
- void speak () override { ... }
- };
- /* 同理,麻雀會飛會唱歌,但是不會說話,所以傳 flyable 和 singable 給 bird template class */
- class sparrow : public bird<flyable, singable>
- {
- public:
- // 不 override fly 成員函式,使用 base class 預設的 fly
- void sing () override { ... }
- };
複製代碼 這個是 C++ 基本的 Policy Based Design,處理的方法和傳統 OO 是不太相同的
因為 C++ 的語言特性支援 type constructor, 所以可以用更高階的方法來做
可以想成一般函數接受值(value)當作參數,並回傳另一個 value
type constructor 也是函數,只是他接受型別(type)作為參數,並回傳另一個 type
像上面的 bird 就是一個 type constructor
你傳 base classes 進去給它,它就會回傳一個繼承了這些 base classes 的型態給你
而且這同樣也是 type safe 的,因為 type 也有型態,叫做 kind (所以或許可以說是 kind safe ? XD)
像是 template <typename... Bases> 就是一個 kind
它規定 bird 能夠接受多少個參數,以及規定參數的 kind 為何
在這個範例裡 bird 可以接受無限多個參數,並且接受的參數必須是無參的
如果上面無法理解,可以對照著這個看
假設有一函數:
int func (char c, int i ) { ... }
和一個 type 層級的函數 (也就是 type constructor):
template <typename T, typename U> struct Func ...;
那麼 func 的型態是: int (char, int)
而 Func 的型態是: typename <typename, typename>
func 拿兩個參數,分別是 char 和 int 型態,並回傳一個 int 型態的參數
Func 也拿兩個參數,都是 typename 型態,並回傳一個 typename 型態的參數
你可以這樣呼叫 func: func ( 'A', 100 );
你可以這樣呼叫 Func: Func<char, float>;
在 value 層級的函數將函數當作參數(Java SE 8):
void func ( Function<int, int> f ) { ... }
在 type 層級的函數將函數當作參數:
template <template <typename> typename F> struct Func ...;
事實上 type constructor 只是 type 層級的函數的一種 (類似 constructor)
如果要泛指 type 層級的函數有一個專用的詞 "type families",不過那是 Haskell 的東西就是了
value 的型別叫做 type,type 的型別叫做 kind,再往上還有 sort, BOX......
這樣也提供了一個 type safe 的方法解決這個問題,而且私心認為比 OO 好多了 orz...
... |
|