Scala 如何使隐式在一个对象中位于另一个对象之前?
考虑到以下情况:Scala 如何使隐式在一个对象中位于另一个对象之前?,scala,scope,implicit,Scala,Scope,Implicit,考虑到以下情况: trait Companion { implicit def str(a: A): String = s"${this.getClass.getSimpleName}: %d" format a.n } class A(val n: Int) object A extends Companion {} class B(val x: Int, y: Int) extends A(y) object B extends Compan
trait Companion {
implicit def str(a: A): String =
s"${this.getClass.getSimpleName}: %d" format a.n
}
class A(val n: Int)
object A extends Companion {}
class B(val x: Int, y: Int) extends A(y)
object B extends Companion {}
现在,编译以下代码将触发发散隐式错误:
val b = new B(5, 2)
val s: String = b
println(s)
因为对象A和AA都在AA的默认隐式范围内。这显然是有缺陷的:类AA比特征A更“精确”,因此它的隐式作用域应该具有更高的优先级。不幸的是,由于对象不能相互继承,因此无法声明这一点
所以我的问题是:在不使用非默认隐式作用域的情况下,实现这一点的最佳方法是什么
现在,编译以下代码将触发发散隐式错误:
val b = new B(5, 2)
val s: String = b
println(s)
这不是“发散性隐性错误”,而是歧义,两者不同
关于类型X
的隐式表达式应转到X
的伴随对象。因此,如果这是A
和String
之间的隐式转换,它应该转到A
的伴生对象。但是您对.getSimpleName
有疑问
常用的方法是参数化同伴对象的父特征(如@MarioGalic):
如果不想将t
设置为类型参数,可以将其设置为类型成员
trait Companion {
type T <: A
implicit def str(a: T): String = s"${this.getClass.getSimpleName}: %d" format a.n
}
class A(val n: Int)
object A extends Companion {
type T = A
}
class B(val x: Int, y: Int) extends A(y)
object B extends Companion {
type T = B
}
或
谢谢!解决方案更加具体,但仍然不是我所要求的,即让一个对象中的隐式覆盖another@tribbloid不存在“一个对象的隐式覆盖另一个对象”的情况。
trait LowPriorityCompanion {
implicit def str(a: A): String = s"${this.getClass.getSimpleName}: %d" format a.n
}
trait Companion extends LowPriorityCompanion {
override implicit def str(a: A): String = super.str(a)
}
class A(val n: Int)
object A extends LowPriorityCompanion
class B(val x: Int, y: Int) extends A(y)
object B extends Companion