object test {
trait Test {
def apply() = {
println("calling apply in trait test")
this
}
}
object Test {
def apply(f: Int => String): Test = {
println("calling apply in object Test")
new Test {
println("test123")
def apply(a: Int) = f(a) // this apply function should be available when call Test(f)?
}
}
}
def fun(a:Int)=a.toString
val f=fun _
val a=Test(f)
a()
a(1) // why this failed? a is created by calling Test(f) which is actually
//calling apply function of object Test, and that function return a Test
//with an addition function of apply(a:Int). And a(1) is actually calling
//apply(1), but why it doesn't compile?
}发布于 2014-06-14 12:18:31
您的签名:
def apply(f: Int => String): Test = { … }将结果限制为被视为Test特性,这不包括新的apply。通过省略结果类型,返回的对象将是一个Test+apply,它将执行您希望它做的事情:
def apply(f: Int => String) = { … }发布于 2014-06-14 10:41:07
这一失败的原因是您的类型Test是用一个接受空参数列表的apply方法定义的。使用new Test { ... },您可以创建Test的匿名子类。虽然使用接受apply参数的另一个版本重载Int,但对象的apply方法的返回类型只是Test。所以从外部看,这个重载的方法是不可见的。
为了说明你的问题:
trait Foo
def mkFoo(): Foo = new Foo { def bar = 1234 }
val f = mkFoo()
f.bar // we don't know anything about bar只需定义您的特性Test,以包含另一个apply方法:
trait Test {
def apply() = {
println("calling apply in trait test")
this
}
def apply(i: Int): String // abstract
}编辑:作为一个完整的问题,如果您使用@samuel的答案中所示的“精化”返回类型,从技术上讲,您使用的是一种“结构化类型”,它附带了一些性能缺陷,因为该方法将使用运行时反射来调用。
https://stackoverflow.com/questions/24218982
复制相似问题