问题
I have a method that looks up some storage for an instance of a particular class:
def lookup[T >: Null: ClassTag]: T = {
// Print what class tag we got:
System.out.println(implicitly[ClassTag[T]].toString);
null; // details omitted, just return null
}
It works well, but the problem is that if I don't provide an explicit type, the compiler chooses Null
for T
, and of course it doesn't work then:
def print(msg: String) = { /* ... */ }
print(lookup);
prints Null
and of course nothing is found. Clearly the compiler infers the least generic type possible.
If I add an explicit type like
print(lookup[String]);
it works fine. But this is very error-prone. I'd like to either:
- Let the compiler to always choose the most generic possible type, instead of the least generic possible one. So in
print(lookup)
the most generic possible type isString
, so I'd like the compiler to inferString
forT
. Or - Force somehow that an explicit type is always present and issue a compile-time error when I write just something like
print(lookup)
.
Is any of this possible?
回答1:
1) Most generic type is AnyRef.
2) You could use =!=
from this answer:
scala> def lookup[T >: Null: ClassTag](implicit guard: T =!= Null ): T = {
| null; // details omitted, just return null
| }
lookup: [T >: Null](implicit evidence$1: scala.reflect.ClassTag[T], implicit guard: =!=[T,Null])T
scala> lookup
<console>:11: error: ambiguous implicit values:
both method equal in trait LowerPriorityImplicits of type [A]=> =!=[A,A]
and method nequal in object =!= of type [A, B](implicit same: =:=[A,B])=!=[A,B]
match expected type =!=[Null,Null]
lookup
^
scala> lookup[String]
res3: String = null
来源:https://stackoverflow.com/questions/16425502/how-to-prevent-compiler-from-choosing-the-least-generic-type