簡體   English   中英

我可以告訴scala如何更喜歡更具體的隱含,而不是給出“含糊不清的”錯誤嗎?

[英]Can I tell scala how to prefer more specific implicit, rather than give “ambiguous implicit” error?

以下代碼給出了錯誤。

class Base { }
class Sub extends Base { }

class Writer[-T] {
  def write(t: T) { }
}

object AmbImplicits {

  implicit object BaseWriter extends Writer[Base]
  implicit object SubWriter extends Writer[Sub]

  def foo[T](t: T)(implicit ev: Writer[T]) {
    println(s"foo $t $ev")
  }

  def main(args: Array[String]) {
    val base = new Base
    val sub = new Sub
    foo(base)
    foo(sub)
  }

}

錯誤:

/Workspace/AmbImplicits.scala:24: error: ambiguous implicit values:
both object SubWriter in object AmbImplicits of type AmbImplicits.SubWriter.type
and object BaseWriter in object AmbImplicits of type AmbImplicits.BaseWriter.type
match expected type Writer[Sub]
    foo(sub)
       ^

在我的真實代碼中,顯式傳遞隱式參數並不是那么簡單。 有沒有辦法告訴它總是喜歡SubWriter不是BaseWriter ,因為前者更具體? 沒有像foo(sub)(SubWriter)那樣手動傳遞它?

如果由於Base和Sub是Java類型而無法完成Shadowlands建議的操作,您可以通過將其移動到繼承鏈來降低BaseWriter隱含的優先級:

trait LowPriorityImplicits { implicit object BaseWriter extends Writer[Base] }

object AmbImplicits extends LowPriorityImplicits {
  implicit object SubWriter extends Writer[Sub]

  def foo[T](t: T)(implicit ev: Writer[T]) {
    println(s"foo $t $ev")
  }

  def main(args: Array[String]) {
    val base = new Base
    val sub = new Sub
    foo(base)
    foo(sub)
  }
}

如果可以,請將隱式對象放在從Base派生的每種類型的伴隨對象中,而不是使用foo方法的對象中:

class Base { }
object Base { implicit object BaseWriter extends Writer[Base] }
class Sub extends Base { }
object Sub { implicit object SubWriter extends Writer[Sub] }

object NotAmbImplicits {

  def foo[T](t: T)(implicit ev: Writer[T]) {
    println(s"foo $t $ev")
  }

  def main(args: Array[String]) {
    val base = new Base
    val sub = new Sub
    foo(base)
    foo(sub)
  }

}

編譯器將在伴隨對象中查找傳遞給foo的給定T ,以查看它是否可以從那里使用隱式。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM