防止推斷沒什麼

基於這篇博文

假設你有這樣的方法:

  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()
}