防止推断没什么

基于这篇博文

假设你有这样的方法:

  def get[T]: Option[T] = ???

当你尝试在不指定泛型参数的情况下调用它时,Nothing 会被推断,这对于实际实现来说并不是非常有用(并且其结果没有用)。使用以下解决方案,NotNothing 上下文绑定可以防止使用该方法而不指定期望的类型(在此示例中,RuntimeClass 也被排除为 ClassTags 而不是 Nothing,但推断 RuntimeClass):

@implicitNotFound("Nothing was inferred")
sealed trait NotNothing[-T]

object NotNothing {
  implicit object notNothing extends NotNothing[Any]
  //We do not want Nothing to be inferred, so make an ambigous implicit
  implicit object `\n The error is because the type parameter was resolved to Nothing` extends NotNothing[Nothing]
  //For classtags, RuntimeClass can also be inferred, so making that ambigous too
  implicit object `\n The error is because the type parameter was resolved to RuntimeClass` extends NotNothing[RuntimeClass]
}

object ObjectStore {
  //Using context bounds
  def get[T: NotNothing]: Option[T] = {
    ???
  }
  
  def newArray[T](length: Int = 10)(implicit ct: ClassTag[T], evNotNothing: NotNothing[T]): Option[Array[T]] = ???
}

用法示例:

object X {
  //Fails to compile
  //val nothingInferred = ObjectStore.get
  
  val anOption = ObjectStore.get[String]
  val optionalArray = ObjectStore.newArray[AnyRef]()
  
  //Fails to compile
  //val runtimeClassInferred = ObjectStore.newArray()
}