我想这样做:
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通常应该是 second 参数列表的一部分,但是我无法弄清楚如何编码它以便编译,并提供我想要的结果。
说明:我正在尝试创建一个框架,其中可以定义“Function”对象,该对象可以依赖于其他函数来计算它们的值。所有函数应该只接受一个Context参数。上下文知道其他函数的“结果”。函数实例应该是不可变的,状态驻留在上下文中。我希望函数在创建时创建“依赖”字段,它隐式地接受上下文,并在该上下文中返回依赖项的值,以便访问apply方法内部的依赖项“感觉比如“访问参数或字段,没有明确地将上下文作为参数提供给依赖项。
答案 0 :(得分:5)
您确定需要Dependency
延长Function
吗?因为如果不这样做,只需将extends Function1[Context,T]
部分保留下来,您的代码即可运行。
如果您确实需要延长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
答案 1 :(得分: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覆盖),因此它可能是实现限制或错误。
答案 2 :(得分:2)
确定,apply
方法签名与implicit
不符合Function1.apply
的签名。
希望我能正确解决你的问题,那么(假设你的context
是可变的,也许是单身的)在创建时注入隐式上下文呢?你的情况可以吗?
class IntDependency(id: Int)(implicit context: Context) extends Dependency[Int](id)
但后来我想知道(之前仍然在想)如何使用context
方法处理apply
参数。
答案 3 :(得分: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)