【问题标题】:Extending FunctionN for a trait implementation为特征实现扩展 FunctionN
【发布时间】:2017-05-03 06:36:40
【问题描述】:

我正在尝试为自己构建一个小型模拟库来处理非常明显的情况:

  1. 模拟函数并记录对它们的调用。
  2. 模拟 trait 实现并能够记录对实现的方法的调用。

我通过以下实现实现的第一个:

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 覆盖任何东西。

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

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

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

【问题讨论】:

    标签: scala


    【解决方案1】:

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

    以这种方式用函数覆盖方法是行不通的,两者是完全不同的东西。见Functions vs methods in Scala

    在您的具体用例中,您可以尝试以下方法:

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

    【讨论】:

    • 我猜你的意思是:apply(i)。这行得通,是的,但你无法联系calls 成员进行自省,因为你又回到了通常的功能。
    • 按照您的建议将您的 LoggedFunction 存储在公共 val 中,这是唯一的方法!
    猜你喜欢
    • 1970-01-01
    • 2019-12-08
    • 2021-11-14
    • 1970-01-01
    • 2015-06-03
    • 1970-01-01
    • 2015-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多