代码之家  ›  专栏  ›  技术社区  ›  user79074

参数化类型的方法重载

  •  4
  • user79074  · 技术社区  · 11 年前

    只是想知道是否有使用参数化类型调用重载方法的方法。例如,定义以下对象:

    object Wrap {
    
            def f(x: X) = println("x called")
            def f(y: Y) = println("y called")
            def f(a: Any) = println("Any")
    
            def fp[T](t: T) = f(t)
    }
    

    当我测试时,拨打以下电话

    Wrap.fp(new X())
    

    它转到呼叫任何。有没有办法让我从fp()调用适当的f?

    3 回复  |  直到 11 年前
        1
  •  3
  •   wheaties    11 年前

    有两种方法:

    第一种方式假设 X Y 是已知类型而不是泛型类型。然后您可以执行以下操作:

     def fp: PartialFunction[Any,Unit] ={
       case x: X => println("got x")
       case y: Y => println("got y")
       case _ => println("Any")
     }
    

    而且不用做太多的健身运动,它也能很好地工作。

    第二种方法是使用类型类:

     def fp[T](t: T)(implicit f: Caller[T]) = f(t)
    

    也就是说,您的类型类可能希望看起来像:

     trait Caller[T]{
       def apply(t: T)
     }
    

    其中你将实际的东西放在范围内,并使用解析顺序来找到最终的 Caller[Any] 所以其他的都优先。所以我会这样做:

     object Wrap{
       implicit val xCal = new Caller[X]{
         def apply(x: X){ println("x called") }
       }
       implicit val yCal = new Caller[Y]{
         def apply(x: Y){ println("y called") }
       }
     }
    
     object `package`{
       implicit val anyCal = new Caller[Any]{
         def apply(t: Any){ println("any") }
       }
     }
    
        2
  •  3
  •   som-snytt    11 年前

    使用类标记进行辅助匹配:

    scala> class W[A: ClassTag] { def f(x: X) = 1; def f(y: Y) = 2; def f(a: A) = 3; 
         | def g(x: Any) = x match {
         | case v: X => f(v); case v: Y => f(v); case v: A => f(v); case _ => -1 } }
    defined class W
    
    scala> trait Z
    defined trait Z
    
    scala> val w = new W[Z]
    w: W[Z] = W@1685b453
    
    scala> w g new X {}
    res6: Int = 1
    
    scala> w g new Y {}
    res7: Int = 2
    
    scala> w g new Z {}
    res8: Int = 3
    
    scala> w g "hi"
    res9: Int = -1
    

    在实际的API中, g 将采用一个类型参数,该类型参数是各种参数的某种超类型,因为并没有人编写采用 Any 这个 T OP中的参数基本上是 任何 ,因为它是不受约束的。

    当我在编辑时,我们忘记了重载是邪恶的。

        3
  •  1
  •   Xiaohe Dong    11 年前
    def process[A](a: A) = a match {
      case c: X => Wrap f c
      case d: Y => Wrap f d
      case _ => Wrap f a 
    }