加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

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

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读