Iva*_*van 12 generics null scala
我正在编写自己的简单javax.sql.DataSource实现,我需要工作的唯一方法是getConnection: Connection,但是接口继承了许多其他方法(我不需要)javax.sql.CommonDataSource和java.sql.Wrapper.所以,我想以一种他们实际上不会工作的方式"实现"那些不需要的方法,但是在调用时会表现得很好.例如,我实现boolean isWrapperFor(Class<?> iface)为
def isWrapperFor(iface: Class[_]): Boolean = false
Run Code Online (Sandbox Code Playgroud)
我想实施<T> T unwrap(Class<T> iface)为
def unwrap[T](iface: Class[T]): T = null
Run Code Online (Sandbox Code Playgroud)
但是最后一个不起作用:编译器报告类型不匹配.
使用是否正确null.asInstanceOf[T]或有更好的方法吗?当然我认为只是UnsupportedOperationException在这个特殊情况下投掷,但恕我直言这个问题仍然很有趣.
dre*_*xin 19
这是因为T可能是非可空类型.它强制执行T为可空类型时有效:
def unwrap[T >: Null](iface: Class[T]): T = null
unwrap(classOf[String]) // compiles
unwrap(classOf[Int]) // does not compile, because Int is not nullable
Run Code Online (Sandbox Code Playgroud)
"正确"的解决方案是做一些会立即失败的事情.像这样:
def unwrap[T](iface: Class[T]): T = sys.error("unimplemented")
Run Code Online (Sandbox Code Playgroud)
在scala 2.10中,这可以实现为:
def unwrap[T](iface: Class[T]): T = ???
Run Code Online (Sandbox Code Playgroud)
因为在Predef调用时有一个新方法???.这是有效的,因为表单的表达式throw new Exception具有类型Nothing,它是任何类型的子类型(在类型 - 理论圆圈中称为底部).
这是正确的原因是,错误立即失败要好得多,而不是使用null可能在以后失败并使原因混淆的错误.