作者godfat (godfat 真常)
看板java
标题Re: [分享] 原来 Void 可以这样用
时间Sat Mar 14 04:28:43 2009
板名再换一下,说真的,有个版叫 PLT... XD
※ 引述《macbuntu (邀怪)》之铭言:
: ※ 引述《godfat (godfat 真常)》之铭言:
: : 於是 Void 就会是所有 class 的 subclass, 然後就可以在任何 overriding
: : method 中把 return type 写成 Void, 因此,就只能够 return null; 也就是
: : Void 唯一可能的 value (instance), 而这个 Void instance (null),
: : 同时也是其他任何 pointer/reference 的可能 value, 因为他是 Void 的
: : instance, class hierarchy 的最底层,相对於 Object 在最顶层。
: 如果 Java 真的放了一个这样的 Void, 会破坏了现在严谨的继承架构,
: 而且除非是 syntax based template, 否则一个真的 wildcard class 已经不能
: 算是符合 covariant return type 的限制了, 从语意到 compiler 都只能当
: 例外状况处理, 这样就不划算了.
当然 Java 不可能会放这种东西,所以当我以为有解的时候,
是感到非常讶异的 XD 同时我也觉得与其说严谨,不如说死板 :s
当然这种说法本身就带有意识形态了。另外如果真的要在 Java 里面做的话,
我觉得最简单的例外就是只允许 Void 有多重继承,然後去继承所有东西即可。
也当然这做法非常粗糙,能带来的好处又非常有限,不如不做。
: 话说回来, 印象中 Scala 就有这种 wildcard type?
: 它还真的有一个 Null class 跟 Nothing class 是 class hierarchy 的最底层,
: 不过我不会写 Scala, 我不知道这只是 internal class 还是 programmer 可以直接
: 使用的型别... 如果 programmer 可以使用, 真好奇 covariant arguments 遇到
: 这种型别要怎麽处理?
Scala 我不熟哩,不过经你一提我大概看了一下 Null 和 Nothing.
http://www.scala-lang.org/docu/files/api/scala/Null.html
http://www.scala-lang.org/docu/files/api/scala/Nothing.html
而 Null 和 Nothing 当然是 programmer 可以用的东西。
至於怎麽用呢?上面那两个连结其实就已经说明了。
Null 应该很好理解吧?就像我上一篇提到的,他只有唯一的一个 instance,
就是 null, 而他也同时是所有 reference type 的 subtype,
所以在原本 sbrhsieh 的例子里:
public interface SomeInterface {
public java.util.List visit(Node node); // return type 不为 Object
}
实作就是:
class SomeVisitor implements SomeInterface{
public Null visit(Node node){
return null; // 这就是唯一选择了
}
}
这边跟你原本用 Void 是一样的。
java.lang.Object
extended by java.lang.Void
你只要把 Null 想像成 Void, 而 java.util.List 想像成 Object 就行了。
只是 Void 只接受 Object, 因为那是他唯一的 parent.
而 Null 接受任何 reference type (也就是不接受 value type),
也不接受 Nothing, 因为 Nothing 比 Null 更底层,其他一律接受。
因为他的 parent 就是以上这些东西。
也像是我原本 C++ 里写的 None<T> 只是更 general, 因为 None<T>
和 None<S> 又是不同的,但是 Scala 的 Null 只有一个!
*
Nothing 就完全是另一回事了。连结上简单的一句话也是一个范例:
For instance, the Scala library defines a value Nil of type
List[Nothing]. Because lists are covariant in Scala, this makes
Nil an instance of List[T], for any element type T.
可以先看到 List 的定义:
sealed abstract class List[+A]
extends Seq[A] with Product
先不用管 Seq[A] 和 Product 是什麽,这边的 List[+A] 表示 list 有一个
covariant subtype relationship, 意思是假使 Integer 是 Object 的
subtype, 则 List[Integer] 也会是 List[Object] 的 subtype.
因此我们定义 Nil 是 List[Nothing] 的 singleton object:
case object Nil
extends List[Nothing]
而由於 Nothing 是所有 type 的 subtype, 所以 List[Nothing] 也是
所有 List[T] 的 subtype. 这意味着尽管我们有无穷多种 List[???],
但是这些 List 的 empty/base value, whatever, 只有一个,就是 Nil.
因此我们可以写:
val any: List[Any] = Nil // Java 语法的话:List[Any] any = Nil
也可以写:
val int: List[Int] = Nil // Java 语法的话:List[Int] int = Nil
因为 Nil 是 List[Nothing] 的 instance, 而 List[Nothing] 是
List[Any] 的 subtype, 也是 List[Int] 的 subtype.
ref:
http://www.scala-lang.org/node/128
==
文件满完整的哩,改天来玩玩看...
另外还有个 JVM 语言是 Clojure,
http://clojure.org/
这是 Lisp 的变种,最近好像满流行的。
不过用起来的感觉我觉得有点怪,Scala 比较漂亮...
--
Hear me exalted spirits. Hear me, be you gods or devils, ye who hold
dominion here:
I am a wizard without a home. I am a wonderer seeking refuge.
Sacrifice
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.135.28.18