How to return null from a generic function in Scal

2019-03-25 02:29发布

I am writing my own simple javax.sql.DataSource implementation, the only method of it I need to work is getConnection: Connection, but the interface inherits many other methods (which I don't need) from javax.sql.CommonDataSource and java.sql.Wrapper. So, I would like to "implement" those unneeded methods a way they wouldn't actually work but would behave an adequate way when called. For example I implement boolean isWrapperFor(Class<?> iface) as

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

and I'd like to implement <T> T unwrap(Class<T> iface) as

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

But the last doesn't work: the compiler reports type mismatch.

Will it be correct to use null.asInstanceOf[T] or is there a better way? Of course I consider just throwing UnsupportedOperationException instead in this particular case, but IMHO the question can still be interesting.

3条回答
【Aperson】
2楼-- · 2019-03-25 02:45

As said in comments, this solution doesn't work

If I understood your problem well, you can also assign default values, as explained in details in what does it mean assign "_" to a field in scala?. You can find more infos in 4.2 Variable Declarations and Definitions of the The Scala Language Specification

So you can simply do:

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

which will set unwrap with null without the type mismatch.

查看更多
手持菜刀,她持情操
3楼-- · 2019-03-25 02:47

The "correct" solution is to do something which will immediately fail. Like so:

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

In scala 2.10, this would have been implemented as:

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

Because there is a new method in Predef called ???. This works because an expression of the form throw new Exception has the type Nothing, which is a subtype of any type (it is called bottom in type-theoretical circles).

The reason that this is correct is that it is much better to fail instantly with an error, rather than use a null which may fail later and obfuscate the cause.

查看更多
对你真心纯属浪费
4楼-- · 2019-03-25 02:54

This is because T could be a non-nullable type. It works when you enforce T to be a nullable type:

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

unwrap(classOf[String]) // compiles

unwrap(classOf[Int]) // does not compile, because Int is not nullable
查看更多
登录 后发表回答