请考虑以下代码:
trait A {
def a : Int
}
def f ( a : Int ) = {
def a0 = a
new A {
def a = a0
}
}
问题很明显:这def a0 = a
是一个典型的烦人的样板代码,当引入更多参数时情况只会变得更糟。
我想知道是否有可能以某种方式a
在 trait 实例的声明中直接引用外部范围的变量,从而摆脱中间a0
.
请记住,不允许更改函数输入参数的名称,因为更改特征也是如此。
我认为没有直接的方法可以做到这一点,因为它需要一些特殊的(假设的)标识符thisMethod
。但是,根据您的上下文,可能有以下两种避免名称隐藏的方法:
(1) 将匿名类替换A
为实现类:
case class AImpl(a: Int) extends A
def f(a : Int): A = AImpl(a)
(2)f
在抽象特征中定义并为其使用具体实现:
trait F {
def f(a: Int): A
}
object FImpl extends F {
def f(a0: Int): A = new A { val a = a0 }
}
def test(factory: F): A = factory.f(a = 33)
我认为你能得到的最接近(不改变你的 API)是:
def f(a: Int) = {
def ff(a0: Int) = {
new A {
def a = a0
}
}
ff(a)
}
在 Scala 中,方法不是类型。因此,不可能使用类型系统或其中的任何成员来引用它们。
scala> class X{def f = 0}
defined class X
scala> import reflect.runtime.universe._
import reflect.runtime.universe._
scala> typeOf[X].member(newTermName("f")).isType
res9: Boolean = false
这是一个匿名的解决方案。
package eyeshadow
trait A {
def a: Int
}
class B {
def f(a: Int) = {
val fa: A = new {
//private val b = a
private[this] val b = a // crashes, sorry scalac. edit: ok in 2.11
} with A {
def a = b
}
fa.a
/*
* This seems far-fetched, but compare the initial objections in
* https://issues.scala-lang.org/browse/SI-3836
* All I want is to alias a symbol, right?
* Maybe the override means "do not shadow."
val fa: A = new A {
//import fa.{ a => b }
import this.{ a => b }
override def b = a
}
*/
}
}
object Test {
def main(args: Array[String]) {
val b = new B
println(b f 7)
}
}