2010-05-12 11 views
6

yılında özellik karıştırılır sınıfın adını alma, biz açıkça adını dönebilirsiniz:Scala: sınıfın bir örneği göz önüne alındığında

trait MixedInClassDiscovery { 
    val className = this.getClass.getName 
} 

class AClass extends MixedInClassDiscovery { 
    ... 
    this.className // returns "AClass" 
    ... 
} 

Ama bu şekilde bir kez AClass her örneği için, yansıma kullanır. Aynı yerine her sınıf için bir kez yapılabilir mi?

Akla gelen bir çözüm, sınıfların kendileri yerine tamamlayıcı nesneler halinde karıştırmaktır.

cevap

1

Ben hiçbir ekstra yükü ile yapmak herhangi bir şekilde düşünemiyorum:

Neyse kodu buraya geliyor. Bununla birlikte, refakatçi nesnelerle yapabileceğini ve işin ekstra parçalarını bir çift: Burada

object Example { 
    trait Discovery { 
    def companion: Discovered 
    def className: String = companion.className 
    } 
    trait Discovered extends Discovery { 
    override lazy val className = { 
     println("Getting class name!") // To see how many times we're called 
     this.getClass.getSuperclass.getName 
    } 
    } 
    class Test extends Discovery { 
    def companion = Test 
    } 
    object Test extends Test with Discovered {} 
} 

Ve biz bu çalıştığını görmek:

scala> val a = new Example.Test 
a: Example.Test = [email protected] 

scala> val b = a.className 
Getting class name! 
b: String = Example$Test 

scala> val c = a.className 
c: String = Example$Test 

ama en çok bir fiyat geliyor: Teşekkür Sınıfı sadece Discovery ile dekore etmekle kalmayıp aynı zamanda eşlik eden yöntemi uygulamalı ve her sınıf için (aynı ada sahip olmayan aynı zamanda) eşlik eden nesneyi yazmalıdır.

1

Pimp lib modelim ile yapabilirsiniz. AnyRef'dan ör. ClassNameAdder. Ancak, bu tür hiyerarşinin bu seviyesinde böyle bir örtülü dönüşüm yaratması önerilmez.

scala> class ClassNameAdder(ref: AnyRef) { def className = ref.getClass.getName } 
    defined class ClassNameAdder 

scala> implicit def anyref2classnameadder(ref: AnyRef) = new ClassNameAdder(ref: AnyRef) 
anyref2classnameadder: (ref: AnyRef)ClassNameAdder 

scala> "foo".className 
res6: java.lang.String = java.lang.String 

scala> new Object().className 
res7: java.lang.String = java.lang.Object 

scala> List(1,2,3).className 
res8: java.lang.String = scala.collection.immutable.$colon$colon 

scala> class MyClass 
defined class MyClass 

scala> val myClass = new MyClass 
myClass: MyClass = [email protected] 

scala> myClass.className 
res9: java.lang.String = MyClass 
+0

Hayır, bu kod hala her örnek için yansıma çağrısı yapıyor. Aslında, her bir 'className' çağrısı için, bu basitçe sabitlenebilir. –

İlgili konular