作者godfat (godfat 真常)
看板PLT
標題Re: [問題] Scala 的 Covariant/Contravariant/Inv …
時間Tue Mar 17 23:58:01 2009
其實我從來沒真的搞懂過 java generic 到底是在做什麼,
只覺得他常常會造成很多的矛盾,讓我感到很困惑,進而放棄使用。
不過經過這一陣子嘗試 scala, 加上 macbuntu 的一些詳細說明,
我才忽然恍然到底是怎麼一回事 @@ 我覺得可以用這兩句話總結:
※ 引述《macbuntu (邀怪)》之銘言:
: Java 的方法表示宣告 variance 的責任落在使用型別的人,
: 而 Scala 的方法表示宣告 variance 的責任落在設計型別的人.
java 要求使用者自行決定 variance 的種類,
而 scala 則反過來要求設計者在設計的時候就說明清楚。
同時,明白表示 +T 只能用在 return type, -T 只能用在 parameter type.
也就是說,就這點上 scala 限制是比 java generic 要來得多。
然而 java 多出來可以做的事:
: static void func(A<? extends Number> a) {
: Number n = a.get(); // OK
: a.set(n); // compile time error
: a.set(123); // compile time error
: a.set(new Object()); // compile time error
: a.set(null); // only this is OK
: }
: 上面那個 func() 裡面, 如果沒有前三個 set() 呼叫, 是可以 compile 沒問題的.
: 但是 T 用在 parameter type 的時候根本不該允許 <? extends Number>
[...其餘見原文]
似乎是沒什麼意義的... :s
: 在使用型別的地方不需要用 <? extends X> 這種東西, 因為這已經定義在 A 裡了,
同時如果 scala 真的需要 upper/lower bound, 也有:
[U <: T] 和 [U >: T] 可以用。就像在 sbrhsieh 裡提到的例子,
這邊 scala 確實也需要:
def assign[U >: String](v: Variable[U], s: String) = v.set(s)
說明 Variable[U] 裡的 U 有個 lower bound 是 String,
可以 pass String 以上(parent)的所有型別。
: 型別不會像 Java 那樣處在不正確的狀態. 習慣 Java 的人會說 Java 用法比較靈活,
: 但我自己覺得 Scala 的 variant 方法是往前更進了一步, 語意也更乾淨漂亮.
: (哈, 語意而已... Scala 的語法我就很難習慣了... Java 中毒太深 :P )
所以看來我是借用 scala 終於比較搞懂 java generic 了 :s
這麼說來 scala generic 確實跟 java generic 很相像,
不愧是設計者有重疊的部份?上次查了一下,java generic 的設計者
好像有一大堆人,其中一個正是 scala 的設計者。
可能是那時候沒想到,也可能是無法說服旁人吧 XD
我沒有查時間順序,或許這也滿令人玩味的。
至於語法的話,我覺得 scala 語法變化性實在很難在短時間內適應,
與其說他特別,不如說可能的寫法滿多的,要到很順手需要一點時間。
尤其 keyword 也一大堆,乍看之下還滿暈頭轉向的。
不過像是 return type 寫在右邊,
這倒是比較符合 functional programming 的風格。
就不曉得會不會兩邊都不討好就是了 :p
--
Nobody can take anything away from him.
Nor can anyone give anything to him.
What came from the sea,
has returned to the sea.
Chrono Cross
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 220.135.28.18