如何防止编译器选择最不通用的类型?

时间:2013-05-07 17:54:21

标签: scala polymorphism type-inference

我有一个方法可以查找某个特定类实例的存储空间:

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
}

它运行良好,但问题是如果我不提供显式类型,编译器会为Null选择T,当然它不起作用:

def print(msg: String) = { /* ... */ }

print(lookup);

打印Null,当然没有找到任何内容。显然,编译器可能推断出最不通用的类型。

如果我添加一个明确的类型,如

print(lookup[String]);

它工作正常。但这非常容易出错。我想要:

  1. 让编译器始终选择最通用的可能类型,而不是最不通用的类型。因此,在print(lookup)中,最通用的可能类型为String,因此我希望编译器推断出String T。或
  2. 以某种方式强制显式类型始终存在,并在我写print(lookup)之类的内容时发出编译时错误。
  3. 这有可能吗?

1 个答案:

答案 0 :(得分:3)

1)大多数通用类型是AnyRef

2)您可以使用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