5

我想做这个:

abstract class Context {
    def getInt(id: Int): Int
}

abstract class Dependency[+T]
(val name: String, val id: Int)
extends Function1[Context,T]

class IntDependency(name: String, id: Int)
extends Dependency[Int](name, id) {
    def apply(implicit context: Context): Int =
        context.getInt(id)
}

但后来我收到这样的错误消息:

class IntDependency needs to be abstract, since method apply in trait
Function1 of type (v1: Context)Long is not defined (Note that T1 does
not match Context)

我知道implicits 通常应该是第二个参数列表的一部分,但我无法弄清楚如何对其进行编码以便编译并给出我想要的结果。

说明:我正在尝试创建一个可以定义“函数”对象的框架,该对象可以依赖于其他函数来计算它们的值。所有函数都应该只接受一个 Context 参数。上下文知道其他功能的“结果”。函数实例应该是不可变的,状态驻留在上下文中。我希望函数在创建时创建“依赖”字段,隐式获取上下文,并在该上下文中返回依赖项的值,以便访问 apply 方法内部的依赖项“感觉就像”访问参数或字段,即没有明确地将上下文作为依赖项的参数。

4

4 回答 4

5

你确定你需要你Dependency的扩展Function吗?因为如果你不这样做,只需留下extends Function1[Context,T]部分,你的代码就会工作。

如果您真的需要扩展 a Function,那么我不知道您的解决方案。但是在某些情况下,您可以尝试重载该apply方法。像这儿:

scala> val sum = new Function1[Int, Function1[Int, Int]] {
         |      def apply(a: Int) = (b: Int) => a + b
         |      def apply(a: Int)(implicit b: Int) = a + b
         |}
sum: java.lang.Object with (Int) => (Int) => Int{def apply(a:Int)(implicit b: Int): Int} = <function1>

scala> sum(2)(3)
res0: Int = 5

scala> implicit val b = 10
b: Int = 10

scala> sum(2)
res1: Int = 12
于 2011-06-19T10:51:21.793 回答
4

一个方法可以将其最终参数部分标记为隐式;它不必是第二部分,尽管这是最常见的。

但似乎当子类将参数部分标记为隐式时,不再考虑覆盖超类中的方法。

scala> new (Int => Int) { def apply(implicit i: Int) = i }
<console>:8: error: object creation impossible, since method apply in trait Function1 of type (v1: Int)Int is not defined
(Note that T1 does not match Int)
       new (Int => Int) { def apply(implicit i: Int) = i }
           ^

scala> trait F1 { def f(a: Any) }; new F1 { def f(implicit a: Any) = () }
<console>:8: error: object creation impossible, since method f in trait F1 of type (a: Any)Unit is not defined
       trait F1 { def f(a: Any) }; new F1 { def f(implicit a: Any) = () }

                                       ^

规范没有特别提到这一点(第 5.1.4 节覆盖),因此它可能是实现限制或错误。

于 2011-06-19T10:21:45.090 回答
2

可以肯定的是,您的apply方法签名 withimplicit不符合Function1.apply. 希望我能解决您的问题,那么(假设您context是可变的并且可能是单例的)在创建时注入隐式上下文呢?在你的情况下这可能吗?

class IntDependency(id: Int)(implicit context: Context) extends Dependency[Int](id)

但是后来我想知道(并且之前仍然想知道)如何处理context该方法的参数apply

于 2011-06-19T10:22:47.617 回答
2

这是工作解决方案:

abstract class Context {
    def getInt(id: Int): Int
}

abstract class Dependency[+T]
(val name: String, val id: Int) {
    def get(context: Context): T
}

class IntDependency(name: String, id: Int)
extends Dependency[Int](name, id) {
    def get(context: Context): Int =
        context.getInt(id)
}

implicit def intDep2Int(dep: IntDependency)
(implicit context: Context): Int =
dep.get(context)
于 2011-06-19T11:36:03.940 回答