2014-09-04 22 views
6

Genellikle bir özellik için bir fabrika yöntemine sahip olduğum ve karşıtların adlarının gizli kalmasına neden olan özellik üyeleriyle çakıştığı durumla karşılaşıyorum:Scala - anonim sınıf oluşturma ve bağımsız değişken adlarının gizlenmesini önleme

argümanlardan

def apply(aA: Int, bB: String): MyTrait = new MyTrait { 
     val a = aA 
     val b = bB 
    } 

veya yapmak yerel kopya:

def apply(a: Int, b: String): MyTrait = { 
     val localA = a 
     val localB = b 

     new MyTrait {   
      val a = localA 
      val b = localB 
    } 
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 
    } 
} 

Yani genelde ben gibi çirkin bir şey yapmak zorunda 0

apply yönteminin parametreleri benim özelliğimin üyeleriyle aynı olmasını istiyorum, böylece istemci kodu, adlandırılmış parametreler kullandığımda güzel okur: ör. MyTrait(a=3,b="123").

Argüman parametrelerinin tanımlandığı dış kapsamı yakalamamı sağlayan bir netleme mekanizması var mı, ancak anonim sınıf henüz yok mu? Örneğin bir şey gibi:

def apply(a: Int, b: String): MyTrait = { outer => 
     new MyTrait { 
      val a = outer.a 
      val b = outer.b 
     } 
    } 

Teşekkürler!

+1

Yinelenen http://stackoverflow.com/q/ 12229005/1296806 –

cevap

2

Bir örnek oluşturmamız gerekiyorsa, neden kurucuya delege etmeyiz. Bu yüzden bu hack düşünebilirsiniz: çok kaydetmez dupe için

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) 
} 
+0

Cevabınız için teşekkürler. Bu özelliğin benim uygulamam, örneğinizde olduğu gibi, verilerden doğrudan geçiyorsa gerçekten işe yarıyor. Bazı uzman uygulamalarını oluşturduğum ve çoğu zaman 'yeni' anahtar kelimesini kullanmam gereken zamanlar vardır. Sorunu vurgulamak için yalnızca örneği basit tutuyordum. – rmin

2

Benim cevap:

trait T { val t: Int } 
object T { 
    def apply(t: Int): T = new { 
    private[this] val x = t 
    } with T { 
    val t = x 
    } 
} 

Ayrıca -optimise alanın kurtulmak etmez.

Farklı bir fikir: param adının diğer adı.

yakında, seçici uyarıları filtrelemek mümkün olacak, yüzden kullanımdan kaldırılması etkinleştirildiğinde oluşturulan uyarıyı göz ardı etmek mümkün olacaktır:

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 = [email protected] 
İlgili konular