15

我正在编写自己的简单javax.sql.DataSource实现,我需要工作的唯一方法是,但是接口从和getConnection: Connection继承了许多其他方法(我不需要)。所以,我想“实现”那些不需要的方法,它们实际上不会起作用,但在调用时会表现得足够好。例如我实现为javax.sql.CommonDataSourcejava.sql.Wrapperboolean isWrapperFor(Class<?> iface)

def isWrapperFor(iface: Class[_]): Boolean = false

我想实现<T> T unwrap(Class<T> iface)

def unwrap[T](iface: Class[T]): T = null

但最后一个不起作用:编译器报告类型不匹配。

使用正确null.asInstanceOf[T]还是有更好的方法?当然UnsupportedOperationException,在这种特殊情况下,我考虑只是扔掉,但恕我直言,这个问题仍然很有趣。

4

3 回答 3

25

这是因为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
于 2012-04-08T20:04:10.483 回答
6

“正确”的解决方案是做一些会立即失败的事情。像这样:

def unwrap[T](iface: Class[T]): T = sys.error("unimplemented")

在 scala 2.10中,这将被实现为:

def unwrap[T](iface: Class[T]): T = ???

因为在Predef被调用中有一个新方法???。这是有效的,因为表单的表达式throw new Exception具有 type Nothing,它是任何类型的子类型(在类型理论圈子中称为底部)。

这是正确的原因是最好立即失败并出现错误,而不是使用null稍后可能会失败并混淆原因的 a 。

于 2012-04-08T22:30:52.147 回答
1

如评论中所述,此解决方案不起作用

如果我很好地理解了您的问题,您还可以分配默认值,详细说明将“_”分配给 scala 中的字段是什么意思?. 您可以在Scala 语言规范的4.2 变量声明和定义中找到更多信息

所以你可以简单地做:

def unwrap[T](iface: Class[T]): T = _

这将设置unwrapnull没有类型不匹配。

于 2012-04-08T21:09:11.923 回答