看板 PLT 關於我們 聯絡資訊
※ 引述《sbrhsieh (sbr)》之銘言: : 你能不能把一個 generic class/interface 宣告為 covariant or contravariant : subtyping 是決定在此 class/interface 的規格上,不是在於你的意圖。而 client : code 要設計成 convariant usage or contravariant usage,是決定在 client code : 的意圖,而不是在於 A 是 A<+T>, A<-T> or A<T>。那為甚麼還需要 variance : annotation? 可以直接從 class/interface 的規格來決定 variance 阿, 這就是我之前提的透過 implicit semantic rule 直接把 Scala 的想法放進 Java 裡 而不加 +/-. 但是 explicit annotation 的好處就如同 @Override 這種東西, 指明意圖後可以讓 compiler 幫我們檢查錯誤. 您前面提到如果有一天 A<+T> 裡面有人加上 set(T t) 這個 method, 變成被逼得只能改成 A<T>, 然後一堆現有的程式變得不能 compile... 這點我倒完全沒想到, 感覺還真是蠻大的缺點... 雖然從嚴謹的角度看, 加上 set(T t) 以後 A 就不是 immutable, 本來就不該繼續允許 covariant T, 但是實務上, Java 的方法能讓現有程式不受影響, 這種妥協感覺蠻值得的. 搞不好這就是 Java 選擇現有設計的原因? 這種東西還真的沒有對錯, 尤其在設計語言的時候, 中間要妥協的灰色地帶很多, Java 的選擇使得 generics type 互相沒有繼承關係, 我覺得有時在語意上表達 就沒那麼直覺, 新手就常常會試著要把 Set<String> 當成 Set<Object> 來用... 但所謂 "直覺" 真是超主觀的. 回到我自己的觀點, 我還是覺得一個 strongly-typed language 會出現 前面說的 set(null) 的狀況, 算是語言設計上的瑕疵. 雖然說 programmer 不要去呼叫它就好了, 但一個好的設計不該出現這種狀態. 從語言使用者的角度, 只要他有辦法用這個語言寫他想要的東西, 這個語言就夠好了. 但從語言設計者的角度, 就是需要在意這種小瑕疵, 才有機會設計更好的語言. 如果能有更好的方法, 讓 generics type 互相有繼承關係, 又可以沒有上面說的 A<+T> 變成 A<T> 的缺陷, 就太好了. -- ※ 發信站: 批踢踢實業坊(ptt.cc) ◆ From: 114.32.132.21