Scala

2012-02-07 14 views
25
Ne yapmaya çalışıyorum, ben onun arkadaşı nesnenin yöntemini demek genel kursuna ve Java dili için (o üzgün statik yöntemini kullanırsınız bir işlev yapmaktır

).Scala

trait Worker {def doSth: Unit} 

class Base 

object Base extends Worker 

// this actually wouldn't work, just to show what I'm trying to achieve 
def callSthStatic[T that companion object is <: Worker](implicit m: Manifest[T]) { 
    // here I want to call T.doSth (on T object) 
    m.getMagicallyCompanionObject.doSth 
} 

Herhangi bir fikir? Scala 2.9.x. kullanılıyorsa

trait Companion[T] { 
    type C 
    def apply() : C 
} 

object Companion { 
    implicit def companion[T](implicit comp : Companion[T]) = comp() 
} 

object TestCompanion { 
    trait Foo 

    object Foo { 
    def bar = "wibble" 

    // Per-companion boilerplate for access via implicit resolution 
    implicit def companion = new Companion[Foo] { 
     type C = Foo.type 
     def apply() = Foo 
    } 
    } 

    import Companion._ 

    val fc = companion[Foo] // Type is Foo.type 
    val s = fc.bar   // bar is accessible 
} 

Bu -Ydependent-method-types bayrağıyla derlenmiş edilmelidir:

cevap

20

A gist by Miles Sabin size bir ipucu verebilir

+0

Gerçek Gist içeriğini ekledim - Gist kaybolabilir ve yalnızca bağlantı, yorum olarak nitelendirilir. –

+0

I "hatası: yasadışı bağımlı yöntem tip örtülü def eşlik [T] (örtük bileşik: Tamamlayıcı [T]) = comp.apply()" alacağım satırında "örtülü def tamamlayıcı [T] (örtük bileşik: Tamamlayıcı [ T]) = comp() "scala ile 2.9.1. Yanlış mı yapıyorum? :-) –

+3

Ben tipi 'Foo' sonra görülebilir eğer öyleyse bu oldukça şık görünüyor rağmen uygulamada kullanışlı olduğunu sanmıyorum bu yüzden, refakatçi nesneymiş olduğunu parantez ekleyeceğiz. –

7

Sen arkadaşı sınıfını ve onun örneğini almak için yansıma kullanabilirsiniz, ama bu bazı uzak (?) Gelecekte değişebilir Scala iç yapıları dayanır. Ve AnyRef aldığınız gibi hiçbir güvenlik yoktur. Ancak sınıflarınıza ve nesnelere herhangi bir ekleme eklemenize gerek yoktur.

def companionOf[T : Manifest] : Option[AnyRef] = try{ 
    val classOfT = implicitly[Manifest[T]].erasure 
    val companionClassName = classOfT.getName + "$" 
    val companionClass = Class.forName(companionClassName) 
    val moduleField = companionClass.getField("MODULE$") 
    Some(moduleField.get(null)) 
} catch { 
    case e => None 
} 

case class A(i : Int) 

companionOf[A].collect{case a : A.type => a(1)} 
// res1: Option[A] = Some(A(1)) 
+0

Teşekkürler, yansıma problemi çözecektir ... scala sürümü güncellemesine kadar, eşlik eden nesnenin adı bu şekilde tutulmayacağı için söz verilmez. –

+1

Eh, bu doğru. Ancak, bu anlaşmanın en azından Scala 2.x günlerinden beri sürdüğünden, isimlendirmenin yakında herhangi bir zamanda değişeceğini düşünmüyorum. – MxFr