如何从Scala中的泛型函数返回null?

时间:2012-04-08 19:53:03

标签: scala generics null

我正在编写自己的简单javax.sql.DataSource实现,我需要使用的唯一方法是getConnection: Connection,但接口继承了许多其他方法(我不需要) javax.sql.CommonDataSourcejava.sql.Wrapper。所以,我想&#34;实施&#34;那些不需要的方法是他们不会实际工作的方式,但在调用时会表现出适当的方式。例如,我将boolean 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,但恕我直言这个问题仍然很有趣。

3 个答案:

答案 0 :(得分:17)

这是因为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

答案 1 :(得分: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形式的表达式具有类型Nothing,它是任何类型的子类型(在类型 - 理论圈中称为 bottom )。

这是正确的的原因是,错误立即失败要好得多,而不是使用可能在以后失败的null并混淆原因。

答案 2 :(得分:1)

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

如果我理解您的问题,您也可以指定默认值,详见what does it mean assign "_" to a field in scala?中所述。您可以在The Scala Language Specification

4.2变量声明和定义中找到更多信息

所以你可以这样做:

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

unwrapnull设置为不匹配类型。

相关问题