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

gmol1639  于 11个月前  发布在  Scala
关注(0)|答案(4)|浏览(119)

我正在编写我自己的简单javax.sql.DataSource实现,我需要工作的唯一方法是getConnection: Connection,但接口继承了许多其他方法(我不需要)从javax.sql.CommonDataSourcejava.sql.Wrapper。我想“实现”这些不需要的方法实际上不会工作,但在调用时会有适当的行为。例如,我将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,但恕我直言,这个问题仍然很有趣。

f3temu5u

f3temu5u1#

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

字符串

r8uurelv

r8uurelv2#

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

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

字符串
在scala2.10中,这将被实现为:

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


因为在Predef中有一个新的方法叫做???。这是因为形式为throw new Exception的表达式具有Nothing类型,这是任何类型的子类型(在类型理论中被称为 bottom)。
这是正确的,因为它是更好地立即失败的错误,而不是使用null,这可能会失败后,混淆的原因。

djmepvbi

djmepvbi3#

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

如果我很好地理解了你的问题,你也可以分配默认值,如what does it mean assign "_" to a field in scala?中的详细说明。你可以在The Scala Language Specification的 *4.2变量声明和定义 * 中找到更多信息。
所以你可以简单地做:

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

字符串
这将用null设置unwrap,而没有类型失配。

yvt65v4c

yvt65v4c4#

您可以使用选项:

def nullHandledFunctionCall[T]( obj: Option[T], function: T=>T ) = {
    if(obj == null){
      None
    }else{
      obj.map(function)
    }
  }

字符串

相关问题