类型、元组、隐式优先级和重载方法
尝试根据第二个参数的类型 Any 与 Throwable 来消除调用哪个方法的歧义,但没有成功。编译下面的代码会生成以下错误消息:
Main.scala:85: error: ambiguous reference to overloaded definition,
both method apply in class Call of type (body: =>(String, Throwable, Array[Any]))(implicit m: Main.Call.Dummy3)Unit
and method apply in class Call of type (body: => (String, Array[Any]))(implicit m: Main.Call.Dummy1)Unit
match argument types ((String, Throwable, String))
agent.call {
^
one error found
这是代码:
object Main {
object Call {
implicit def t1(t: Tuple2[String, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2))
}
implicit def t1t(t: Tuple2[String, Throwable]): Tuple2[String, Throwable] = {
(t._1, t._2)
}
implicit def t2(t: Tuple3[String, Any, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2, t._3))
}
implicit def t2t(t: Tuple3[String, Throwable, Any]): Tuple3[String, Throwable, Array[Any]] = {
(t._1, t._2, Array(t._3))
}
class Dummy1
object Dummy1 {
implicit def dummyImplicit: Dummy1 = {
println("Dummy1.dummyImplicit")
new Dummy1
}
}
class Dummy2
object Dummy2 {
implicit def dummyImplicit: Dummy2 = {
println("Dummy2.dummyImplicit")
new Dummy2
}
}
class Dummy3
object Dummy3 {
implicit def dummyImplicit: Dummy3 = {
println("Dummy3.dummyImplicit")
new Dummy3
}
}
}
import Call._
class Call {
def apply(body: => Tuple2[String, Array[Any]])
(implicit m: Dummy1): Unit = {
println("message and array of parameters")
}
def apply(body: => Tuple2[String, Throwable])
(implicit m: Dummy2): Unit = {
println("message and throwable")
}
def apply(body: => Tuple3[String, Throwable, Array[Any]])
(implicit m: Dummy3): Unit = {
println("message, throwable and array of parameters")
}
}
class Agent {
val _call = new Call
def call: Call = _call
}
def main(args: Array[String]): Unit = {
val msg = "XXX"
val agent = new Agent
agent.call {
(msg, "one")
}
agent.call {
(msg, new Exception)
}
agent.call {
(msg, "one", "two")
}
agent.call {
(msg, new Exception, "one")
}
}
}
我尝试按如下方式降低“t2”的优先级:
trait LowPriority {
implicit def t2(t: Tuple3[String, Any, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2, t._3))
}
}
object Call extends LowPriority {
....
}
并从“Call”对象中删除“t2”,但得到了相同的错误消息。
我希望消歧发生在编译时而不是运行时。 谢谢。
Trying to disambiguate which method is called based upon the type of the second parameter, Any vs. Throwable, but without success. Compiling the code below generates the following error message:
Main.scala:85: error: ambiguous reference to overloaded definition,
both method apply in class Call of type (body: =>(String, Throwable, Array[Any]))(implicit m: Main.Call.Dummy3)Unit
and method apply in class Call of type (body: => (String, Array[Any]))(implicit m: Main.Call.Dummy1)Unit
match argument types ((String, Throwable, String))
agent.call {
^
one error found
Here's the code:
object Main {
object Call {
implicit def t1(t: Tuple2[String, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2))
}
implicit def t1t(t: Tuple2[String, Throwable]): Tuple2[String, Throwable] = {
(t._1, t._2)
}
implicit def t2(t: Tuple3[String, Any, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2, t._3))
}
implicit def t2t(t: Tuple3[String, Throwable, Any]): Tuple3[String, Throwable, Array[Any]] = {
(t._1, t._2, Array(t._3))
}
class Dummy1
object Dummy1 {
implicit def dummyImplicit: Dummy1 = {
println("Dummy1.dummyImplicit")
new Dummy1
}
}
class Dummy2
object Dummy2 {
implicit def dummyImplicit: Dummy2 = {
println("Dummy2.dummyImplicit")
new Dummy2
}
}
class Dummy3
object Dummy3 {
implicit def dummyImplicit: Dummy3 = {
println("Dummy3.dummyImplicit")
new Dummy3
}
}
}
import Call._
class Call {
def apply(body: => Tuple2[String, Array[Any]])
(implicit m: Dummy1): Unit = {
println("message and array of parameters")
}
def apply(body: => Tuple2[String, Throwable])
(implicit m: Dummy2): Unit = {
println("message and throwable")
}
def apply(body: => Tuple3[String, Throwable, Array[Any]])
(implicit m: Dummy3): Unit = {
println("message, throwable and array of parameters")
}
}
class Agent {
val _call = new Call
def call: Call = _call
}
def main(args: Array[String]): Unit = {
val msg = "XXX"
val agent = new Agent
agent.call {
(msg, "one")
}
agent.call {
(msg, new Exception)
}
agent.call {
(msg, "one", "two")
}
agent.call {
(msg, new Exception, "one")
}
}
}
I tried making the "t2" lower priority as follows:
trait LowPriority {
implicit def t2(t: Tuple3[String, Any, Any]): Tuple2[String, Array[Any]] = {
(t._1, Array(t._2, t._3))
}
}
object Call extends LowPriority {
....
}
and removing "t2" from the "Call" object, but got the same error message.
I would like the disambiguation to take place at compile-time and not at run-time.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
Miles Sabin 为我提供了以下解决方案:
Miles Sabin provided me with the following solution: