Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to return null from a generic function in Scala?

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.

like image 521
Ivan Avatar asked Apr 08 '12 19:04

Ivan


People also ask

How do I return a generic null?

So, to return a null or default value from a generic method we can make use default(). default(T) will return the default object of the type which is provided.

How do I use generic in Scala?

To use a generic class, put the type in the square brackets in place of A . Class Apple and Banana both extend Fruit so we can push instances apple and banana onto the stack of Fruit . Note: subtyping of generic types is *invariant*.

What is generic function in Scala?

One of the best ways to understand use cases for generic classes is to look at examples in the Scala standard library. Most Scala generic classes are collections, such as the immutable List, Queue, Set, Map, or their mutable equivalents, and Stack. Collections are containers of zero or more objects.

Can int be null in Scala?

The reference types such as Objects, and Strings can be nulland the value types such as Int, Double, Long, etc, cannot be null, the null in Scala is analogous to the null in Java.


2 Answers

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
like image 157
drexin Avatar answered Sep 20 '22 12:09

drexin


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.

like image 44
oxbow_lakes Avatar answered Sep 21 '22 12:09

oxbow_lakes