scala – 类型,元组,隐式优先级和重载方法
发布时间:2020-12-16 18:32:34 所属栏目:安全 来源:网络整理
导读:尝试消除根据第二个参数的类型(Any vs. Throwable)调用哪个方法的歧义,但没有成功.编译下面的代码会生成以下错误消息: Main.scala:85: error: ambiguous reference to overloaded definition,both method apply in class Call of type (body: =(String,Thro
尝试消除根据第二个参数的类型(Any vs. 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,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,Array(t._2,t._3)) } implicit def t2t(t: Tuple3[String,Any]): Tuple3[String,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,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,t._3)) } } object Call extends LowPriority { .... } 并从“调用”对象中删除“t2”,但得到相同的错误消息. 我希望消除歧义在编译时而不是在运行时进行. 解决方法
Miles Sabin为我提供了以下解决方案:
object Main { object Call { trait LowPriorityDistinguishThrowable { trait Wrap1[A,B] { val body : (A,B) def apply(call: Call) : Unit } trait Wrap2[A,B,Any] { val body : (A,Any) def apply(call: Call) : Unit } implicit def wrap11[T](body0 : => (String,T)) = new Wrap1[String,T] { lazy val body = body0 def apply(call: Call) { println("(message and not throwable): " +body) } } implicit def wrap21[T](body0 : => (String,T,Any)) = new Wrap2[String,Any] { lazy val body = body0 def apply(call: Call) { println("(message and not throwable): " +body) } } } object DistinguishThrowable extends LowPriorityDistinguishThrowable { implicit def wrap12(body0 : => (String,Throwable)) = new Wrap1[String,Throwable] { lazy val body = body0 def apply(call: Call) { println("(message and throwable): " +body) } } implicit def wrap22(body0 : => (String,Any] { lazy val body = body0 def apply(call: Call) { println("(message and throwable): " +body) } } } } class Call(val enabled: Boolean) { import Call._ import DistinguishThrowable._ def apply[T](body: Wrap1[String,T]): Unit = { if (enabled) body(this) } def apply[T](body: Wrap2[String,Any]): Unit = { if (enabled) body(this) } } def main(args : Array[String]): Unit = { val call = new Call(true) call { ("foo",new Exception) } call { ("foo","bar") } call { ("foo","one") } call { ("foo","bar","one") } } } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |