扩展功能N以实现特征实现

时间:2017-05-03 06:36:40

标签: scala

我正在努力建立一个小型的模拟库来处理非常明显的案例:

  1. 模拟功能并记录对它们的调用。
  2. 模拟特征实现,并能够记录对所实现方法的调用。
  3. 我通过以下实现获得的第一个:

    class LoggedFunction1[A1, B](body: A1 => B) extends Function1[A1, B] {
        val calls = mutable.Buffer[A1]()
    
        override def apply(v1: A1): B = {
            calls += v1
            body(v1)
        }
    }
    
    object LoggedFunction {
        def apply[A1, B](body: A1 => B) = new LoggedFunction1(body)
    }
    

    到目前为止,非常好。

    我现在想知道是否可以以某种方式使用此FunctionN扩展来实现特征的方法,例如:

    trait A {
        def m(i: Int)
    }
    
    class B extends A {
        override def m(i: Int) = LoggedFunction((a: Int) => a)
    }
    

    现在当然不会编译,因为m的返回值必须是Int类型而不是Function1[Int, Int]

    我可以声明一个伴随值来包含我的信息,例如:

    class C extends A {
        val _m = LoggedFunction((a: Int) => a)
        override def m(i: Int) = _m(i)
    }
    

    但是,好吧。我真正想做的是:

    class D extends A {
        override val m = LoggedFunction((a: Int) => a)
    }
    

    在我看来,最新的“应该”以某种方式起作用,因为我用Function1[Int, Int]覆盖Function1[Int, Int],但它抱怨我没有用m覆盖任何内容。

    我是否有可能使用我的m覆盖LoggedFunction,所以我最终写了:

    val test = new E
    test.m(1)
    test.m.calls should have size 1
    

    如果不是:为什么不可能用包含函数的值覆盖方法?

1 个答案:

答案 0 :(得分:2)

  

在我看来,最新的“应该”以某种方式起作用,因为我用Function1[Int, Int]覆盖Function1[Int, Int]

用这种方式覆盖一个方法是不行的,两者是完全不同的东西。请参阅Functions vs methods in Scala

在您的确切用例中,您可以尝试以下操作:

override def m(i: Int) = LoggedFunction((a: Int) => a).apply(i)