请考虑以下代码:
trait A {
def a : Int
}
def f ( a : Int ) = {
def a0 = a
new A {
def a = a0
}
}
问题非常明显:def a0 = a
是典型的烦人样板代码,只有引入更多参数时情况才会恶化。
我想知道是否有可能以某种方式直接引用特征实例声明中外部范围的a
变量,从而摆脱中间a0
。
请记住,不允许更改功能的输入参数名称,因为更改特性。
答案 0 :(得分:4)
我认为没有直接方法,因为它需要一些特殊的(假设的)标识符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)
答案 1 :(得分:3)
我认为您最接近的(不更改您的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
答案 2 :(得分:3)
这是一个匿名解决方案。
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)
}
}