我正在编写自己的简单javax.sql.DataSource
实现,我需要使用的唯一方法是getConnection: Connection
,但接口继承了许多其他方法(我不需要) javax.sql.CommonDataSource
和java.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
,但恕我直言这个问题仍然很有趣。
答案 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 = _
将unwrap
与null
设置为不匹配类型。