PLT 板


LINE

看板 PLT  RSS
※ 引述《sbrhsieh (sbr)》之铭言: : : interface A<+T> { : : public T get(); // OK : : } : : interface C<-T> { : : public void set(T t); // OK : : } : : interface E<T> { : : public T get(); // OK : : public void set(T t); // OK : : } : 我认为 generic type 大部分会是上述的 interface E 这种型态居多,这种类型 : 的 generic type 在 scala 里只能定义为 non-variant subtyping,那麽用上此 : feature 的机会不多。 我觉得因为 Java type parameter 是 invariant 的, 所以看不出 A 和 C 的好处. 举个使用 covariant type 的例子 (pseudo java): interface Set<+T> { public T get(); } class Algorithm { public static Number findMax(Set<Number> s) { .... } } // 下面都可以用, 因为 type parameter 是 covariant Set<Integer> si = /* new ... */; Integer i = Algorithm.findMax(si); Set<Double> sd = /* new ... */; Double d =Algorithm.findMax(sd); 实务上常常会有很多东西可以被 model 成 immutable object, 只能读取不能修改, 如果使用 generics 来设计这些东西, parameterized type 之间能有继承的关系, 譬如可以设计成 IPod 继承 Product 则 Parts<IPod> 继承 Parts<Product>, 我觉得很多时候会蛮直觉的. : 第二,我认为不应该是由 generic type 来决定 subtyping variance,而是由 : client code 来决定。 : ,,, : 如果一个 Java programmer 没有对 wildcard/bounded wildcard 有足够的观念, : 那麽即使把 scala Variance Annotations 加入 Java PL,对他们不会带来多大的 : 好处(因为 Variable 这种类型的 generic type 占大多数)。 这就很难说哪样比较好了... 两种方法虽然表面上看起来都可以做到一样的事, 譬如我上面举的例子您可能说宣告 findMax(Set<? extends Number> a) 就好了, 但这两种方法有一个微妙的差别: Java 的方法表示宣告 variance 的责任落在使用型别的人, 而 Scala 的方法表示宣告 variance 的责任落在设计型别的人. 我本来以为 Java 的方法比较保守, 但後来仔细看了 Scala 後, 反而觉得 Java 的方法比较乱, 虽然可以活用, 但这样活用的代价是型别会被允许处在一个 语意不正确的状态. 我来举个例子: interface A<T> { public T get(); public void set(T t); } 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> 这种 covariant binding, 也就是说, Java compiler 允许 A 处在一个不正确 的状态, 让 A.set() 变成完全无用, 只能放 null 进去. 只允许 s.set(null) 从语意上就变得说不通了, 原先的 A<T> 可以 a.set(a.get()) 为什麽 进到 func() 里後不能 a.set(a.get())? 是因为 A 里的 T 只该允许 invariant. Scala 的方法让整个 type polymorphism 变得很一致, 即使有 type parameter 还是可以有继承的关系. Type parameter variance 的能力跟本来就 T 在型别里面 使用的位置有直接的关系, 所以宣告 variance 的责任落在设计型别的人身上, 感觉既合理又清楚. 如此一来, 使用型别的人没有办法以错误的方法使用它, 所以上面的例子用 Scala 的方法来写的话, 设计 A 的人当初如果宣告 A<T>, 是 invariant, 则没有变成 covariant/contravariant 的机会: interface A<T> { .... } void func(A<Number> a) { ... } A<Integer> i = /* new something */ func(i); // compile time error A<Object> o = /* new something */ func(o); // compile time error A<Number> n = /* new something */ func(n); // OK 如果需要 covariant 或是 invariant, 当初设计 A 的人就要设计一个是可以允许 +T 或是 -T 的介面, 将来才可以这样用: interface A<+T> { .... } void func(A<Number> a) { ... } A<Integer> i = /* new something */ func(i); // OK A<Object> o = /* new something */ func(o); // compile time error A<Number> n = /* new something */ func(n); // OK 在使用型别的地方不需要用 <? extends X> 这种东西, 因为这已经定义在 A 里了, 型别不会像 Java 那样处在不正确的状态. 习惯 Java 的人会说 Java 用法比较灵活, 但我自己觉得 Scala 的 variant 方法是往前更进了一步, 语意也更乾净漂亮. (哈, 语意而已... Scala 的语法我就很难习惯了... Java 中毒太深 :P ) --



※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 60.251.144.115







like.gif 您可能会有兴趣的文章
icon.png[问题/行为] 猫晚上进房间会不会有憋尿问题
icon.pngRe: [闲聊] 选了错误的女孩成为魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一张
icon.png[心得] EMS高领长版毛衣.墨小楼MC1002
icon.png[分享] 丹龙隔热纸GE55+33+22
icon.png[问题] 清洗洗衣机
icon.png[寻物] 窗台下的空间
icon.png[闲聊] 双极の女神1 木魔爵
icon.png[售车] 新竹 1997 march 1297cc 白色 四门
icon.png[讨论] 能从照片感受到摄影者心情吗
icon.png[狂贺] 贺贺贺贺 贺!岛村卯月!总选举NO.1
icon.png[难过] 羡慕白皮肤的女生
icon.png阅读文章
icon.png[黑特]
icon.png[问题] SBK S1安装於安全帽位置
icon.png[分享] 旧woo100绝版开箱!!
icon.pngRe: [无言] 关於小包卫生纸
icon.png[开箱] E5-2683V3 RX480Strix 快睿C1 简单测试
icon.png[心得] 苍の海贼龙 地狱 执行者16PT
icon.png[售车] 1999年Virage iO 1.8EXi
icon.png[心得] 挑战33 LV10 狮子座pt solo
icon.png[闲聊] 手把手教你不被桶之新手主购教学
icon.png[分享] Civic Type R 量产版官方照无预警流出
icon.png[售车] Golf 4 2.0 银色 自排
icon.png[出售] Graco提篮汽座(有底座)2000元诚可议
icon.png[问题] 请问补牙材质掉了还能再补吗?(台中半年内
icon.png[问题] 44th 单曲 生写竟然都给重复的啊啊!
icon.png[心得] 华南红卡/icash 核卡
icon.png[问题] 拔牙矫正这样正常吗
icon.png[赠送] 老莫高业 初业 102年版
icon.png[情报] 三大行动支付 本季掀战火
icon.png[宝宝] 博客来Amos水蜡笔5/1特价五折
icon.pngRe: [心得] 新鲜人一些面试分享
icon.png[心得] 苍の海贼龙 地狱 麒麟25PT
icon.pngRe: [闲聊] (君の名は。雷慎入) 君名二创漫画翻译
icon.pngRe: [闲聊] OGN中场影片:失踪人口局 (英文字幕)
icon.png[问题] 台湾大哥大4G讯号差
icon.png[出售] [全国]全新千寻侘草LED灯, 水草

请输入看板名称,例如:BuyTogether站内搜寻

TOP