我经常遇到这样的情况,即我有一些特征的工厂方法,并且参数的名称与特征的成员冲突导致它们被隐藏:
trait MyTrait {
val a: Int
val b: String
}
object MyTrait {
def apply(a: Int, b: String): MyTrait = new MyTrait {
val a = a // Recursive infinite loop.
val b = b
}
}
所以通常我必须做一些丑陋的事情:
def apply(aA: Int, bB: String): MyTrait = new MyTrait {
val a = aA
val b = bB
}
或制作参数的本地副本:
def apply(a: Int, b: String): MyTrait = {
val localA = a
val localB = b
new MyTrait {
val a = localA
val b = localB
}
我希望apply
方法的参数与我的特征成员相同,以便在使用命名参数时客户端代码可以很好地读取: MyTrait(a=3,b="123")
。
是否有一个更整洁的机制让我捕获定义参数参数的外部范围,但是匿名类还没有?例如:
def apply(a: Int, b: String): MyTrait = { outer =>
new MyTrait {
val a = outer.a
val b = outer.b
}
}
谢谢!
答案 0 :(得分:2)
如果我们需要创建一个实例,为什么不将它委托给构造函数。所以我可以想到这个黑客:
trait MyTrait {
def a: Int
def b: String
}
object MyTrait {
private class MkMyTrait(val a: Int, val b: String) extends MyTrait
def apply(a: Int, b: String): MyTrait = new MkMyTrait(a, b)
}
答案 1 :(得分:2)
我对骗局的回答,并没有节省多少:
trait T { val t: Int }
object T {
def apply(t: Int): T = new {
private[this] val x = t
} with T {
val t = x
}
}
另外,-optimise并没有摆脱这个领域。
这是一个不同的想法:别名为param名称。
很快,我们将能够有选择地过滤警告,因此可以忽略启用弃用时生成的警告:
scala> :pa
// Entering paste mode (ctrl-D to finish)
trait T { val t: Int }
object T {
def apply(@deprecatedName('t) t0: Int): T = new T { val t = t0 }
}
// Exiting paste mode, now interpreting.
defined trait T
defined object T
scala> T(t = 42)
warning: there was one deprecation warning; re-run with -deprecation for details
res1: T = T$$anon$1@6ea1bcdc